#!/usr/bin/env bash
ME="[todisc]:"
. tovid-init 2>/dev/null ||
{ echo -e "===============================================================\n"
echo -e "'tovid-init' not found.  Was tovid improperly installed?"
echo -e "Or are you trying to run the script directly?"
echo -e "Please run todisc as:\ntovid disc OPTIONS"
exit 1 ; }
# todisc
# Part of the tovid suite
# =======================
# A bash script for generating a DVD
# with many styles of animated and static menus,
# from a collection of MPEG video files.
#
# Project homepage: http://tovid.wikia.com
#
# Copyright (C) 2005-2010
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
#
#     http://www.gnu.org/licenses/gpl.txt

# Mostly written by Robert Sohn:
#     <grepper@gmail.com>
#     grepper on irc.freenode.net

SCRIPT_NAME=`cat << EOF
--------------------------------
todisc
Generate a DVD filesystem with animated thumbnail menus
Part of the tovid suite, version $TOVID_VERSION
$TOVID_HOME_PAGE
--------------------------------
EOF`

USAGE=`cat << EOF
Usage:
    todisc [OPTIONS] \\\\
      -files File1.mpg File2.mpg ... \\\\
      -titles "Title 1" "Title 2" ... \\\\
      -out OUT_PREFIX
You can also do slideshows using -slides IMAGES rather than -files VIDEOS
See the tovid manual page ('man tovid') for additional documentation.

EOF`
# check that needed todisc deps are installed
assert_dep "$todisc_deps"
SCRIPT_START_TIME=`date +%s`

# check if symlink in /tmp exists and use time stamped link if so
WORK_DIR="/tmp/todisc-work"

LOG_FILE=$(readlink -f todisc.log)
OUT_PREFIX=""
TV_STANDARD=ntsc
MENU_LEN=( 20 )
USER_MENU_LEN=false
USER_SUBMENU_LEN=false
SUBMENU_LEN=(10)
MAX_MENU_LEN=""
TARGET=dvd
FRAME_RATE=29.970
VIDSIZE=720x480
MENU_TITLE="My Video Collection"
STATIC=false
SUB_MENU=false
ANI_SUB_MENU=false
TITLE_CLR="#EAEAEA"
SM_TITLE_CLR="#EAEAEA"
THUMB_BG_CLR=white
TITLES_CLR=""
BUTTON_STYLE="rect"
MIST_COLOUR=white
MIST_OPACITY=60
TITLE_STROKE=""
SUBMENU_STROKE="none"
BG_AUDIO=""
BG_PIC=""
BG_VIDEO=""
SHOWCASE=false
SUBMENU_AUDIO=false
SM_AUDIO_FADE=:
SM_FADE=1
AUDIO_FADE=:
OPACITY=100
MENU_FADE=false
FIRST_PIC=0
TRANSPARENT=false
PREVIEW=:
PAUSE_TIME=10
USER_LOOP=false
MIST=false
FEATHER=false
THUMB_BLUR=1
SC_BLUR=1
SUB_MENU_FEATHER=false
IMG_FMT="jpg"
SM_IMG_FMT="jpg"  # submenu image format
KEEP_FILES=false
THUMB_SHAPE=""
SEEK_VAL=2
USER_SEEK_VAL=false
FADE=1
CHAPTERS=( 6 )
TOVID_OPTS=()
CHAIN_VIDEOS=false
NOASK=false
SC_FRAMESTYLE="none"
THUMB_FRAME_SIZE="3x3"
THUMB_FRAME_CLR='#444744'
SHOWCASE_FRAME_SIZE=4x4
SHOWCASE_FRAME_CLR='#6E6E6E'
SHOWCASE_VIDEO=""
THREExONE=false
FOURxONE=false
PLAYALL=false
AUTHOR_PLAYALL=false # needed for VMGM playall logic
THUMBS_3D=false
SHOWCASE_3D=false
RAISE=""
CURVE_UPDATE=""
SUBTITLES=false
USER_BSTYLE=false
SHOWCASE_SEEK_VAL=2
BG_SEEK=2
BG_AUDIO_SEEK=2
USER_BG_AUDIO_SEEK=false
USER_SM_AUDIO_SEEK=false
SC_THUMB=:
TEXTMENU=false
SC_TITLE_ALIGN=center
THUMB_TITLE_ALIGN=center
ALIGN_OVERRIDE=false
MULTILINE_TITLE=false
SAFE_AREA=50 # undocumented: you can set this from CLI with -showcase-safe-area
SAFE_OFFSET=36
ASPECT_RATIO=4:3
AR=1.333
ASPECT_ARG=all
WIDE_SCREEN=false
WIDESCREEN="nopanscan"
GROUPING=false
TEXT_YSTART=$SAFE_AREA
BUTTON_GRAVITY=north
XGEO=0
YGEO=45
USER_GRAVITY=false
USER_GEO=false
USER_SPLIT=false
TITLE_GRAVITY=south
SPACER=15
SELECT_CLR="#DE7F7C"
HLIGHT_CLR="#266CAE"
USER_SC_GEO=false
USER_SAFE_AREA=false
USER_TITLE_GEO=false
SPACER=""
SE_YCORNER=0
WARN=true
ROTATE_THUMBS=false
DO_TITLESETS=false
AUTHOR=:
ts_start=0
args=( "$@" )
VMGM_ONLY=false
TITLESET_MODE=false
TSET_NUM=1
MENU_NUM=1
INTRO=""
QUICK_NAV=false
SKIP_VMGM_MENU=false
VMGM_MENU=:
# recursing titlesets need to set logic for returning to root menu (playall)
VMGM_PLAYALL=false
MONTAGE_MENU=:
NO_TOP_MENU=false
DO_MENU=:
DO_STATS=:
DO_FRAME=:
DO_BUTTONS=:
SWITCHED_MENUS=false
SWITCHED_MODE=false
SWITCHED=false
TSET_MODE=false
TSET_TOT=1
NONAME=false
DO_INTRO=false
USE_MPLAYER_4AUDIO=false
MENU_AUDIOLEN=""
USER_AUDIOLENGTH=false
BURN=false
BURN_DEVICE="/dev/dvdrw"
QUICK_MENU=false
BG_CLR='#101010'
SUBMENU_BG_CLR='#101010'
QM_PREVIEW=false
USER_CHAPTERS=false
QUICKMENU_IS_SHOWCASE=false
QUICKMENU_IS_BACKGROUND=false
CAROUSEL_IS_BG=false
CAROUSEL_IS_SHOWCASE=false
RESIZE_BG=false
DO_CAROUSEL=false
is_carousel=false
UNDERCOLOUR="000000"
SLIDE_FADE=false
SINGLE_SLIDESHOW=false
MK_CAROUSEL_MODE=false
MTG_GEO="+12+6"
VIDEOS_ARE_CHAPTERS=false
CONFIRM_BACKUP=:
USE_FEATHER_MASK=false
DO_BINNING=:
BINMAX=640
USE_FFMPEG=:
USE_DVD_SLIDESHOW=false
SLIDE_BLUR_OPT="0x0.4"
USERS_BACKGROUND=false
SFRAME_CLR="#EAEAEA"
EFFECT="crossfade"
num_bgpics=0
num_scpics=0
TRANSITION_TO_MENU=false
DEBUG=false
pngpipe="-quality 01 png:-"
ani_pics=0
JUSTIFY="center"
CONTRAST_CLR='gray'
NOMENU=false
SC_AR=133
THUMB_COLUMNS=""
TOVID_PREFIX=$(tovid -prefix)

##############################################################################
#                                 Functions                                  #
##############################################################################

# Y-echo: echo to two places at once (stdout and logfile)
# Output is preceded by the script name that produced it
# Args: $@ == any text string
# If no args are given, echo a separator bar
# Use yecho if you want output to go to the logfile
yecho()
{
    if test $# -eq 0; then
        printf "\n%s\n\n" "$SEPARATOR"
        # If logfile exists, copy output to it (with pretty formatting)
        test -e "$LOG_FILE" && \
        printf "%s\n%s %s\n%s\n" "$ME" "$ME" "$SEPARATOR" "$ME" >> "$LOG_FILE"
    else
        sed "s/    */ /g;s/^ *//" <<< "$@" | fold -bs
        test -e "$LOG_FILE" && \
            printf "%s %s\n" "$ME" "$@" | sed "s/    */ /g;s/^ *//" |
            fold -bs >> "$LOG_FILE"
    fi
}
# ******************************************************************************
# Execute the given command-line string, with appropriate stream redirection
# Args: $@ == text string containing complete command-line
# Returns: Exit status of the subprocess
# To filter/prettify the subprocess output before writing it to the log file,
# set the LOG_FILTER variable before calling this function, to e.g.
#    LOG_FILTER="sed 's/\r/\r\n/g'"    # Replace LF with CR/LF
# ******************************************************************************

# Print script name, usage notes, and optional error message, then exit.
# Args: $@ == text string(s) containing error message and help
usage_error()
{
    MESSAGE=( "$@" )
    printf "%s\n%s\n%s\n\n" "$USAGE" "$SEPARATOR" "***"
    for ((i=0; i<$#; i++)) ; do printf "%s" "${MESSAGE[i]}"; done |format_output
    printf "\n\n%s\n" "***"
    ! $KEEP_FILES && rm -rf "$REAL_WORK_DIR" "$WORK_DIR"
    if $SWITCHED_MODE ||$SWITCHED_MENUS ||$TITLESET_MODE ||$DO_TITLESETS; then
        killall_instances
    fi
    exit 1
}
warning_message()
{
    local MESSAGE=( "$@" )
    yecho $SEPARATOR
    for ((i=0; i<$#; i++)) ; do printf "%s" "${MESSAGE[i]}"; done |
    format_output | tee -a "$LOG_FILE"
    echo | tee -a "$LOG_FILE"
    yecho "$SEPARATOR"
}

titlesafe_error()
{
    echo "***** WARNING *****"
    yecho "thumb title is $1 pixels from screen edge"
    yecho "Part of the title may not be visible on your tv screen"
    yecho "Perhaps use a smaller -titles-fontsize, or shorten \"${TITLES[i]}\""
    $SHOWCASE && [[ -z $SHOWCASE_FILE ]] && \
    yecho "You may also use '-showcase-titles-align-east' since you are not
    using a -showcase FILE."
    echo "****************************"
    $WARN && sleep 5
}

format_output()
{
    sed "s/    */ /g;s/^ *//"|fold -bs
}

get_font()
{
    # If there is a filename extension, find the absolute path
    if grep -q '\...*$' <<< "$1"; then
        readlink -f "$1"
    # Otherwise, use the literal name
    else
        echo "$1"
    fi
    # TODO: Check for font availability?
}

vid_length()
{
    check_frames=""
    [[ -n $2 ]] && check_frames=$2 && check_frames="-frames $check_frames"
    echo "Using mencoder to get length of $1" >> "$LOG_FILE"
    L=$(mencoder -nosound -mc 0 -oac pcm -ovc copy $check_frames \
    -o /dev/null "$1" 2> /dev/null)
    awk 'END{print $(NF-3)}' <<< "$L"
}
audio_length()
{
    mplayer -noconsolecontrols -vo null -ao pcm:fast:file=/dev/null "$1" \
    2>&1 | tr '\r' '\n' | grep ^A: | tail -1 | sed s/^.*A:// | awk '{print $1}'
}
cleanup()
{
    #TODO make a kill_pid function to avoid repetition below
    # and/or consider just using pkill
    echo >&2
    echo "Cleaning up..." >&2
    pids2kill="$impids $smpids $bgfade_pids $title_pids $tcode_pids $encpids"
    for pidfile in "$WORK_DIR/tcode*.pid"; do
        if [[ -s $pidfile ]]; then
            if kill -0 $(<$pidfile) 2> /dev/null; then
                kill $(<$pidfile) 2> /dev/null
                sleep .3
            fi
            if kill -0 $(<$pidfile) 2> /dev/null; then
                kill -9 $(<$pidfile) 2> /dev/null
            fi
        fi
    done
    for PID in $impids $smpids; do
        if kill -0 $PID  2> /dev/null; then
            children=$(pgrep -P $PID)
                for child in $children; do
                    if kill -0 $child 2>/dev/null; then
                        kill $child 2>/dev/null
                        sleep .3
                    fi
                    if kill -0 $child 2>/dev/null; then
                        kill -9 $child 2>/dev/null
                    fi
                done
        fi
    done
    for PID in $pids2kill; do
        if kill -0 $PID  2> /dev/null; then
            kill $PID  2> /dev/null
            sleep .3
        fi
        if kill -0 $PID  2> /dev/null; then
            kill -9 $PID  2> /dev/null
        fi
    done
    if $KEEP_FILES; then
        echo "Keeping temporary files in $REAL_WORK_DIR" >&2
        [[ -n $SUPPORT_VIDEOS ]] && yecho "Keeping ${SUPPORT_VIDEOS[@]}" && \
            yecho "This sliced video will not work if todisc is run with
             different seeks so should be deleted manually"
    else
        if [[ -d $REAL_WORK_DIR ]]; then
            [[ -n $SUPPORT_VIDEOS ]] && yecho \
            "Removing "${SUPPORT_VIDEOS[@]}"" >&2 && \
            rm -f "${SUPPORT_VIDEOS[@]}" >&2
            #echo -n "Removing $REAL_WORK_DIR ..." >&2
            rm -rf "$REAL_WORK_DIR" >&2
        fi
    fi
    #yecho "Removing the symlink in /tmp" >&2 | tee -a "$LOG_FILE"
    rm -f "$WORK_DIR" >&2
}
# exit from all recursive todisc calls
killall_instances()
{
    for P in $TODISC_PIDS ; do
        kill $P
    done
}

# ******************************************************************************
# Print out a runtime error specified as an argument, and exit
# ******************************************************************************
runtime_error()
{
    # Uncomment if needed later
    #killsubprocs
    echo
    echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    yecho "todisc encountered an error:"
    yecho "    $@"
    echo
    echo "Check the contents of $LOG_FILE to see what went wrong."
    echo "See the tovid website ($TOVID_HOME_PAGE) for what to do next."
    echo "Sorry for the inconvenience!"
    echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    cleanup
    if $SWITCHED || $TITLESET_MODE || $DO_TITLESETS; then
        killall_instances
    fi
    exit 1
}

running_total()
{
    LC_ALL="C" awk -v offset=$offset '{
    for (i=1; i<=NF; i++) if (s=s+$i) printf("%s ",s);printf ("\n")}'
}

awk_total()
{
    LC_ALL="C" awk '{for (i=1; i<=NF; i++) s=s+$i}; END{print s}'
}

# format seconds to 00:00:00.000 format
format_seconds()
{
    LC_ALL="C"  awk '{
    hr=($1/3600); hd=(sprintf("%02d", hr))
    mr=((hr-hd)*60); md=(sprintf("%02d", mr))
    s=((mr-md)*60); sd=(sprintf("%02d", s))
    t=(sprintf("%02d:%02d:%06.3f" ,hd,md,s)); print t}' <<< $1
}

# generic function for using bc for floating point math
# usage: bc_math "expression" [int]
bc_math()
{
    bc_out=$(bc <<< "scale=3;$1" 2>/dev/null)
    if [[ -n $2 && $2 = "int" ]]; then
        echo ${bc_out%.*}
    else
        printf  "%.03f" $bc_out
    fi
}

confirm_preview()
{
    confirm_msg="type 'yes' to continue, or press <ENTER> to exit: "
    yecho
    if $SWITCHED || $TITLESET_MODE || $VMGM_ONLY; then
        echo "If doing titlesets or switched menus and you wish to exit "
        echo "without seeing more previews, then type: 'exit', else you will "
        echo "continue on with other previews even if you don't type 'yes'."
        echo
        confirm_msg="read above paragraph and then $confirm_msg"
    fi
    echo "If you are happy with the preview, $confirm_msg"
    read input
    echo
    if [ ! -z "$input" -a "$input" = "yes" ]; then
        yecho "Preview OK, continuing."
        yecho
    else
        yecho "Preview not OK, exiting."
        #echo -n "Deleting symlink in /tmp . . . "
        echo "Cleaning up..."
        rm -f "$WORK_DIR"
        if $KEEP_FILES; then
            echo "Keeping temporary files in $REAL_WORK_DIR"
        else
            #echo -n "Deleting "$REAL_WORK_DIR" . . . "
            rm -fr "$REAL_WORK_DIR"
        fi
        yecho
        echo
        echo "Some configuration options to try, if things look bad:"
        echo "Color:"
        echo "    -title-color"
        echo "    -titles-color"
        echo "Fonts:"
        echo "    -menu-font and -menu-fontsize"
        echo "    -titles-font and -titles-fontsize"
        echo "If your titles are not clear enough or look washed out,"
        echo "try a larger font, or setting -title-stroke and -titles-stroke"
        echo "to a contrasting color.  Or set the strokes to the same color"
        echo "as your titles.  For black frames look at the -seek option."
        echo "For other fine-tuning options, see 'man tovid'."
        echo
        [ ! -z "$input" -a "$input" = "exit" ] && killall_instances
        exit 0
    fi
}

# Display (echo) a spinner with a message
SP=0
spin()
{
    SPIN_CHARS=".oOo"
    SPINNER="${SPIN_CHARS:SP++%${#SPIN_CHARS}:1}"
    # Print spaces to overwrite previous line
    echo -ne "\r                                                            "
    echo -ne "\r$@ "
}

#EXPAND="expand=-6:-6,"
get_framed_pics()
{
mplayer -ss $MPLAYER_SEEK_VAL -vo $VOUT -noconsolecontrols \
-vf ${EXPAND}rectangle=${FRAME_SIZE/x*}:${FRAME_SIZE/*x},rectangle=$(( \
${FRAME_SIZE/x*} - D )):$(( ${FRAME_SIZE/*x} - D)),rectangle=$(( \
${FRAME_SIZE/x*} - $((D * 2)) )):$(( ${FRAME_SIZE/*x} - \
$((D * 2)) )),rectangle=$(( ${FRAME_SIZE/x*} - $((D * 3)) )):$(( \
${FRAME_SIZE/*x} - $((D * 3)) )) \
-nosound -zoom -x ${FRAME_SIZE/x*} -y ${FRAME_SIZE/*x}  -frames $FRAMES "$1"
}

stat_logfile()
{
    stat -L -c "%Y" "$LOG_FILE"
}

get_line_count()
{
awk 'END{print NR}' "$LOG_FILE"
}

# hack to check if transcode is stalling and set it a HUP if so
# usage: check_stall PID
check_stall()
{
    PIDOF_TRANSCODE=$1
    newlines=$(stat_logfile)
    while ps -p $PIDOF_TRANSCODE >/dev/null; do
        # Check for transcode output every 10 seconds
        sleep 10
        age=$newage
        newage=$(stat_logfile)
        # If no new output, sleep 20s and check again
        [[ $newage = $age ]] && sleep 20 && newage=$(stat_logfile)
        # If still no new lines, send a HUP signal to transcode
        if [[ $newage == $age ]] \
        && kill -0 $PIDOF_TRANSCODE > /dev/null 2>&1; then
            echo
            echo "*** transcode appears to be stalled ***"
            echo "*** Sending transcode a HUP and hoping for the best ***"
            sleep 5
            $(kill -0 $PIDOF_TRANSCODE > /dev/null 2>&1) && \
            kill -HUP $PIDOF_TRANSCODE
            echo
        fi
    done
}
check_filetype()
{
    fstats=$(file -L "$1")
    if [[ $fstats =~ "image" || $fstats =~ "bitmap" ]]; then
        TYPE="image"
        CONVRT=:
        if [[ $fstats = *JPEG* || $fstats = *PNG || $fstas = *PPM* ]]; then
            CONVRT=false
        fi
    elif mencoder \
    -endpos 2 -oac pcm -ovc copy "$1" -o /dev/null >/dev/null 2>&1; then
        TYPE=video
    else
        TYPE=unknown
    fi
}

get_stats()
{
unset IN_STATS FILES_IN
this_set=$1
if [[ $this_set = "group" ]]; then
    unset TOT IN_STATS FILES_IN
    TOT=${#grouping[@]} # || TOT=${#IN_FILES[@]}
    IN_STATS=( "${group_idvid_stats[@]}" )
    FILES_IN=( "${grouping[@]}" )
else
    TOT=${#IN_FILES[@]}
    IN_STATS=( "${idvid_stats[@]}" )
    FILES_IN=( "${IN_FILES[@]}" )
fi
for ((i=0; i<TOT; i++)); do
    VCODEC="$(awk -F= '/ID_VIDEO_FORMAT/ {print $2}'    <<< "${IN_STATS[i]}")"
    V_BR="$(awk -F= '/ID_VIDEO_BITRATE/ {print $2}'    <<< "${IN_STATS[i]}")"
    ACODEC="$(awk -F= '/ID_AUDIO_CODEC/ {print $2}'    <<< "${IN_STATS[i]}")"
    A_BR="$(awk -F= '/ID_AUDIO_BITRATE/ {print $2}'    <<< "${IN_STATS[i]}")"
    if [ -z "$A_BR" ]; then
        A_BR="No audio found"
    fi
    V_LENGTH=${VID_LEN[i]}
    [[ $this_set = "group" ]] && V_LENGTH=${GROUP_VID_LEN[i]}
    FPS="$(awk -F= '/ID_VIDEO_FPS/ {print $2}'    <<< "${IN_STATS[i]}")"
    yecho
    if [[ $this_set = "group" ]] && ((i == 0)); then
        echo; echo ". . . Grouped file stats . . ."; echo
    yecho
    fi
    [[ $this_set = "group" ]] && echo -e "Stats for" \
    $(readlink -f "${FILES_IN[i]}") "\n" || \
    echo -e "Stats for" "${FILES_IN[i]}" "\n"
    echo -e  \
    " video codec:   " \
    "$VCODEC" "\n" \
    "video bitrate: " "$V_BR" "bits per second" "\n" \
    "framerate:     " "$FPS" "fps" "\n" \
    "audio codec:   " \
    "$ACODEC" "\n" \
    "audio bitrate: " \
    "$A_BR" "bits per second" "\n" \
    "video length:  " \
    "$V_LENGTH" "seconds" |tee -a "$LOG_FILE"
done
}
test_compliance()
{
    file_in="$1"
    if idvid -isformat ${TV_STANDARD}-${TARGET} "$file_in" >/dev/null; then
        :
    else
        return 1
    fi
}


check_compliance()
{
    # slide mpg's go in $WORK_DIR, and are moved to BASEDIR later if recursing
    # for video files: files are named $IN_FILE.enc.mpg
    unset FILES_TO_ENCODE ENC_IN_FILES CHECK_IN_FILES
    group_set=false
    if [[ $1 = "group" ]]; then
        group_set=:
        unset x a
        CHECK_IN_FILES=( "${grouping[@]}" )
    else
        CHECK_IN_FILES=( "${IN_FILES[@]}" )
    fi
    TEMP_FILE="$WORK_DIR/temp.mpg"
    stime=$(date +%s)
    for ((i=0; i<${#CHECK_IN_FILES[@]}; i++)); do
        # save slideshow temporary files in $WORK_DIR
        IN_FILE=${CHECK_IN_FILES[i]}
        if $group_set; then
            is_image=${grp_file_is_image[i]}
            # replace the symlink with actual mpeg
            OUTFILE="$WORK_DIR/${CHECK_IN_FILES[i]##*/}"
        else
            is_image=${file_is_image[i]}
            # replace the symlink with actual mpeg
            OUTFILE="$WORK_DIR/${TSET_NUM}-$((i+1)).mpg"
        fi

        spin "Checking compliance of file $((i+1))"
        # if file tested as an image when we were verifying input files
        if [[ $is_image = "yes" ]]; then
            $group_set && grp_use_image2mpeg2[i]="yes" ||
            use_image2mpeg2[i]="yes"
            FILES_TO_ENCODE[i]=$IN_FILE
            NO_PROMPT_FILES[i]=$IN_FILE
            ENC_IN_FILES=("${ENC_IN_FILES[@]}" "$WORK_DIR/${OUTFILE##*/}")
            # for titlesets we need to move all encoded mpegs to $BASEDIR
        # do not reencode animated slideshow m2v's made by MK_CAROUSEL_MODE
        elif ! $group_set && [[ ${CAROUSEL[i]} = "carousel" ]]; then
            ENC_IN_FILES=("${ENC_IN_FILES[@]}" "$IN_FILE")
        # test files with idvid script
        elif test_compliance "$IN_FILE" && [[ ${TOVID_OPTS[@]} != *-force* ]] ; then
            ENC_IN_FILES=("${ENC_IN_FILES[@]}" "$IN_FILE")
        # Video needs to be re-encoded; use a .enc filename in ENC_IN_FILES
        else
            FILES_TO_ENCODE[i]=$IN_FILE
            ENC_IN_FILES=("${ENC_IN_FILES[@]}" "${IN_FILE}.enc.mpg")
        fi
    done
    $DEBUG && etime=$(date +%s) && get_elapsed "compliance check"
    if test "${#FILES_TO_ENCODE[@]}" -gt 0; then
        TGT_CAPS=$(tr a-z A-Z <<< "$TARGET")
        TV_STND_CAPS=$(tr a-z A-Z <<< "$TV_STANDARD")
        echo
        yecho "Encode input files"
        if ! $SINGLE_SLIDESHOW; then
            echo
            yecho "Some of the -files you provided are not \
            $TV_STND_CAPS $TGT_CAPS-compliant:"
            echo " "
        fi
        if test ${#FILES_TO_ENCODE[@]} -lt 12 && ! $SINGLE_SLIDESHOW; then
            for i in "${FILES_TO_ENCODE[@]}"; do
                this_file=$(readlink -f "$i")
                test -n "$this_file" && yecho " $this_file"
            done
        fi
        # this ugly list of OR's are cases we want automatic encoding
        # all switched runs except the 1st, if -no-ask, if single slideshow
        # or if all input files are images
        if { $SWITCHED && [[ $MENU_NUM -ne 2 ]] ; } \
         || $NOASK || [[ ${TOVID_OPTS[@]} = *-noask* ]] || \
         [[ ${#NO_PROMPT_FILES[@]} = ${#FILES_TO_ENCODE[@]} ]]; then
            yecho " "
            echo "Encoding files to $TV_STND_CAPS $TGT_CAPS-compliant format."
            echo "(This may take a long time)"
            ENCODE="yes"
        else
            yecho " "
            yecho "I can encode them for you, but it may take a long time."
            yecho "Encoding will ensure that your disc is fully compliant;"
            yecho "you may skip this, but your disc may not be playable."
            yecho "Please type 'yes' if you want the files to be encoded:"
            read ENCODE
        fi
        if test -n "$ENCODE" && test "$ENCODE" = 'yes'; then
            if ! $SINGLE_SLIDESHOW; then
                yecho
                yecho "Converting files to $TGT_CAPS format"
                yecho
            fi
            for i in "${!FILES_TO_ENCODE[@]}"; do
                IN=$(readlink -f "${FILES_TO_ENCODE[i]}")
                if $group_set; then
                    is_image=${grp_file_is_image[i]}
                    # we will replace the symlink with actual mpeg
                    OUTFILE="$WORK_DIR/${CHECK_IN_FILES[i]##*/}"
                else
                    is_image=${file_is_image[i]}
                    # we will replace the symlink with actual mpeg
                    OUTFILE="$WORK_DIR/${TSET_NUM}-$((i+1)).mpg"
                fi
                if $group_set; then
                    convert_image=${grp_use_image2mpeg2[i]}
                else
                    convert_image=${use_image2mpeg2[i]}
                fi

                if [[ $convert_image = "yes" ]]; then
                    # group: test if $OUTFILE is symlink (ie. not encoded yet)
                    # files: test if $OUTFILE doesn't exist
                    if [[ -L $OUTFILE || ! -e $OUTFILE ]]; then
                        spin "Processing" "${IN##*/}"
                        image2mpeg2 "$IN" "$TEMP_FILE"
                        # replace the symlink in $WORK_DIR
                        rm -f "$WORK_DIR/${OUTFILE##*/}"
                        mv "$TEMP_FILE" "$WORK_DIR/${OUTFILE##*/}"
                    fi
                    # AUDIO_FADE=false # do not fade silence FIXME ???
                else # not an image file - outfile goes beside infile
                    THIS_FILE=$(readlink -f "${FILES_TO_ENCODE[i]}")
                    yecho "Converting $THIS_FILE"
                    echo
                    countdown 3
                    TOVID_WORKING_DIR=$WORKING_DIR makempg $NO_ASK \
                    -$TV_STANDARD -$TARGET -in "$IN" -out "${IN}.enc" "${TOVID_OPTS[@]}"
                    # for grouped files replace symlink in $WORK_DIR
                    $group_set && [[ -L "${FILES_TO_ENCODE[i]}" ]] && \
                    ln -sf "${IN}.enc.mpg" "${FILES_TO_ENCODE[i]}"
                fi
                wait
                # See if output file exists
                if [[ $convert_image = "yes" ]]; then
                    test_file="$WORK_DIR/${OUTFILE##*/}"
                else
                    test_file="${IN}.enc.mpg"
                fi
                if ! test -f "$test_file"; then
                    KEEP_FILES=:
                    runtime_error "Could not encode file: $IN"
                fi
                #yecho
            done

            # Replace IN_FILES with ENC_IN_FILES (with .enc extension)
            # for grouped files the mpeg already replaced the group symlink
            ! $group_set && IN_FILES=("${ENC_IN_FILES[@]}")
        else
            yecho
            yecho "Not re-encoding. I will proceed with menu generation, but"
            yecho "your authored disc will not be fully $TGT_CAPS-compliant."
            yecho
        fi
    fi
}

# check bgvideo and showcase VIDEO for compliance
tovid_reencode()
{
    VIDEO_IN="$1"
    VIDEO_IN_SEEK="$2"
    video_type=$3
    yecho
    yecho "$VIDEO_IN is not compliant - re-encoding
      $(bc <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null)
        second slice to DVD compliant file"
    yecho "For long seeks this will take some time and produce a large file."
    yecho "But if the file is not encoded this way there may be sync problems."
    yecho "Do you want to continue encoding this file?, type 'yes' to do so"
    if ! $NOASK; then
        read response
        if [ ! -z "$response" -a "$response" = "yes" ]; then
            :
        else
            return
        fi
    fi
    yecho
    yecho "Converting files to $TGT_CAPS format with 'makempg'"
    countdown
    makempg $NO_ASK -in "$VIDEO_IN" \
    -slice 0-$(bc <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null) \
    -${TV_STANDARD} -${TARGET} -in "$VIDEO_IN" \
    -out "${VIDEO_IN}.enc" "${TOVID_OPTS[@]}"
    # See if output file exists
    if ! test -f "${VIDEO_IN}.enc.mpg"; then
        runtime_error "Could not encode file: $VIDEO_IN"
    else
        [[ $video_type = showcase ]] && SHOWCASE_VIDEO="${VIDEO_IN}.enc.mpg"
        [[ $video_type = background ]] && BG_VIDEO="${VIDEO_IN}.enc.mpg"
    fi
    SUPPORT_VIDEOS=( "${SUPPORT_VIDEOS[@]}" "${VIDEO_IN}.enc.mpg" )
    yecho
}

mk_workdir()
{
    REAL_WORK_DIR=$(tempdir "$WORKING_DIR/todisc-work")
    sleep .5 # avoid race condition
    WORK_DIR=$(tempdir /tmp/todisc-work nocreate)
    # tempdir() made a unique name with nocreate, now make it a symlink
    ln -sf "$REAL_WORK_DIR" "$WORK_DIR"
}


get_group_chapters()
{
    FORMAT=false
    index=$1
    [[ -n $2 && $2 = "format" ]] && FORMAT=:
    $USER_CHAPTERS && FORMAT=false
    unset chapt_len_array x len remainder y e grp_chapters array
    remainder=0
    chapter_length=$( bc_math "${GROUP_TOT_LEN[index]} / ${CHAPTERS[index]}")
    GROUP_VIDEO_LENGTHS=( ${GROUP_VID_LENGTHS[index]} )
    if $USER_CHAPTERS; then
        unset grp_arb_chts y
        grp_arb_chts=( ${group_arbitrary_chapters[index]} )

        for y in ${!grp_arb_chts[@]}; do
            unset GC
            (( y == 0 )) && chpts0="chapters=\"${grp_arb_chts[y]}\""
            gc=( ${grp_arb_chts[y]//,/ } )
            # allow passing 00:00:00 for grouped chapters
            ((${#gc[@]} == 1 )) && [[ $gc = 00:00:00* ]] && gc=( 00:00:01 )

            for g in ${gc[@]}; do GC="$GC $(unformat_time $g)"; done
            grp_chapters[y]=$GC
            if [[ ${grp_arb_chts[y]} = 0 ]]; then
                chpts[y]=""
            else
                chpts[y]=chapters=\"${grp_arb_chts[y]}\"
            fi
        done
    else
        for len in ${GROUP_VIDEO_LENGTHS[@]}; do
            adjusted_length=$( bc <<< "scale=3; $len + $remainder" 2>/dev/null)
            num_chapters=$( bc_math "$adjusted_length / $chapter_length" int )
            if (( num_chapters > 0)); then
                chapt_len_array=( $( for ((t=0; t<num_chapters; t++)); do
                echo $chapter_length; done) )
                chapt_len_array=($(bc_math "$chapter_length - $remainder") \
                ${chapt_len_array[@]})
                unset chapt_len_array[${#chapt_len_array[@]}-1]
                chapter_points=$( running_total <<< ${chapt_len_array[@]} )
                # remove trailing space
                chapter_points=$(sed 's/[ \t]*$//' <<< $chapter_points)
                remainder=$( bc <<< "$adjusted_length % $chapter_length" \
                2>/dev/null)
                (( ${nochapt[index]} )) && local group_chapters[x++]=0 ||
                local group_chapters[x++]=$chapter_points
            else
                (( ${nochapt[index]} )) && local group_chapters[x++]=0 ||
                local group_chapters[x++]=""
                remainder=$adjusted_length
            fi
        unset chapt_len_array
        done
        # remove last chapter as this makes one for the end of the video
        # ignore if we are doing -chapters 0 for this video ( no chapters )
        if ! ((${nochapt[index]})); then
            for id in ${!group_chapters[@]}; do
                for s in ${group_chapters[id]}; do
                    let p=p+1
                    (( p < ${CHAPTERS[index]})) && substr="$substr $s"
                done
                group_chapters[id]=$substr
                unset substr
            done
        fi

        unset remainder
        for d in ${!group_chapters[@]}; do
            for number in ${group_chapters[d]}; do
                new_element="$new_element $(format_seconds $number),"
                grp_chapters[d]="${grp_chapters[d]} $number"
                grp_chapters[d]=$(sed 's/[ \t]*$//' <<< ${grp_chapters[d]})
            done
            local array[d]=$new_element
            unset new_element
        done

    fi
    if $FORMAT; then
        for e in ${!array[@]}; do
            points=$(for f in ${array[e]// /}; do echo -n $f;done)
            if [[ -z ${array[e]} ]]; then
                [[ -n ${chapts[e]} ]] && unset chpts[e]
            else
                chpts[e]=chapters=\"${points%,}\"
            fi
            [[ -n ${array[e]} ]] && chpts[e]=${chpts[e]#,}
            if ((e == 0)); then
                if [[ -z "$points" ]]; then
                    chpts0="chapters=\"00:00:00\""
                else
                    chpts0="chapters=\"00:00:00,${points%,}\""
                fi
            fi
            #chpts=${chpts[@]#,} # I have no idea why this worked with this here
        done
    fi
}

get_image_dim()
{
    identify -ping "$1" | awk '{print $3}'
}

get_button_geo()
{
    GEOx=${MENU_BUTTON_SIZE/x*}
    GEOy=${MENU_BUTTON_SIZE/*x}
    GEOx=$((GEOx - 3))
    GEOy=$((GEOy - 3))
    GEO="$GEOx,$GEOy"
}

# this function takes a 4:3 image and gives a new height to make it 16:9
get_177_ht()
{
    image_width=$1
    bc_math "($image_width * 9)/16" int
}

get_ntsc_ht()
{
    img_width=$1
    bc_math "(2 * $img_width)/3" int
}

get_pal_ht()
{
    img_width=$1
    bc_math "(4 * $img_width)/5" int
}
image2mpeg2()
{
    IN_IMAGE="$1"
    OUT_MPEG="$2"
    # remove symlinks, as otherwise we overwrite symlink target
    IMAGE_ENC_CMD=(ffmpeg -f image2 -loop_input -vframes $vlength \
    -i "$IN_IMAGE" -s $VIDSIZE -f s16le -i /dev/zero -t $alength \
    -ar $SAMPLERATE -ac 2 -ab 224k -target ${TV_STANDARD}-${TARGET} \
    -aspect $ASPECT_RATIO -y "$OUT_MPEG")
    echo "Running ${IMAGE_ENC_CMD[@]}" | format_output >> "$LOG_FILE"
    "${IMAGE_ENC_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"
}

switched_menu_mode()
#call todisc recursively to make multiple menus for -switched-menus option
{
    $TITLESET_MODE && IS_TITLESET="-is_titleset"
    for ((i=1; i<${#FILES[@]}; i++)); do
        yecho
        yecho "Working on switched menu $((i+1))"
        $WARN && yecho && sleep 5
        yecho "Running todisc "$@" -switched-mode $IS_TITLESET \
        -basedir "$BASEDIR" -menu_num $((i+1)) -showcase "${FILES[i]}""
        todisc "$@" -switched-mode $IS_TITLESET -basedir "$WORK_DIR" \
        -menu_num $((i+1)) -todisc_pids "$TODISC_PIDS" -showcase "${FILES[i]}"
    done
        yecho
        yecho "Working on switched menu 1"
        yecho
#    exit
}
carousel_menu_mode()
# call todisc recursively to make animated slideshow menu
{
    mk_carousel()
    {
        unset menulen
        c=$1 # carousel index ( 0 based )
        ! $CONFIRM_BACKUP && NO_CONFIRM_BACKUP="-no-confirm-backup"
        if [[ $sstype = "submenu" ]]; then
            menulen="-menu-length ${SUBMENU_LEN[c]}"
            mixrange=${SM_MIX_RANGE[c]}
        else
            $USER_MENU_LEN && menulen="-menu-length ${MENU_LEN[c]}"
            mixrange=${MIX_RANGE[c]}
        fi
        if [[ -n $mixrange ]]; then
            if (($mixrange<${#IN_SLIDES[@]})); then
                mix_range="-menu-slide-total $mixrange"
            else
                unset mix_range
            fi
        else
            unset mix_range
        fi
        MC_CMD=(todisc -slides "${IN_SLIDES[@]}" $mix_range \
        $NO_CONFIRM_BACKUP ${encopt[@]} $sld_tranition $background_carousel \
        $showcase_carousel -out "$OUT_PREFIX" -carousel_menu_mode -basedir \
        "$WORK_DIR" $menulen -carousel_num $((c+1)) -todisc_pids "$TODISC_PIDS")
        yecho
        yecho "Running ${MC_CMD[@]}"
        "${MC_CMD[@]}"
    }

    [[ -n $1 ]]  && local sstype=$1 || local sstype=""
    $SLIDE_FADE && sld_tranition="-slide-transition $EFFECT"
    #! grep -q -- -noask <<< "$TOVID_OPTS" && \
    [[ ${TOVID_OPTS[@]} != *-noask* ]] && \
     encopt=("${TOVID_OPTS[@]}" -noask)
    if $CAROUSEL_IS_BG && [[ $sstype != "submenu" ]]; then
        local background_carousel="-background-slideshow"
        IN_SLIDES=( "$WORK_DIR"/${TSET_NUM}-slide_grp*.mpg )
        mk_carousel 0
    elif $CAROUSEL_IS_SHOWCASE && [[ $sstype != "submenu" ]]; then
        local showcase_carousel="-showcase-slideshow"
        IN_SLIDES=( "$WORK_DIR"/${TSET_NUM}-slide_grp*.mpg )
        mk_carousel 0
    else
        for i in ${!FILES[@]}; do
            if ${SLIDESHOW[i]}; then
                unset IN_SLIDES sl
                for sld in "$WORK_DIR"/${TSET_NUM}-slide_grp-$((i+1))-*.mpg; do
                    IN_SLIDES[sl++]=$sld
                done
                yecho
                yecho "Working on carousel menu $((i+1))"
                yecho
                mk_carousel $i
            fi
        done
    fi

}
# used by titleset_mode()
get_genopts()
{
    unset GEN_OPTS
    i=0
    while [[ $@ ]]; do
        case "$1" in
            "-titleset")
                shift
                while [[ $@ && $1 != "-end-titleset" ]]; do
                    tsetopt="$tsetopt $1"
                    shift
                done
                tsetopts=( "${tsetopts[@]}" "$tsetopt" )
                unset tsetopt
                ;;
            "-vmgm")
                shift
                while [[ $@ && $1 != "-end-vmgm" ]]; do
                    vmgmopts="$vmgmopts $1"
                    shift
                done
                ;;
            "-group")
                shift
                get_listargs "$@"
                ;;
            *)
                GEN_OPTS[i++]="$1"
                ;;
        esac
        shift
    done
}
# used by get_titleset_opts() within titleset_mode()
get_title_count()
{
    unset y titles
    while [[ $@ ]]; do
        case "$1" in
            "-vmgm")
                while [[ $@ && $1 != "-end-vmgm" ]]; do
                    shift
                done
                ;;
            "-files" )
                shift
                get_listargs "$@"
                fls=( "${fls[@]}" "${#ARGS_ARRAY[@]}")
                ;;
            "-slides" )
                fls=( "${fls[@]}" 1)
                ;;
        esac
        shift
    done
    NUM_TITLES=( "${NUM_TITLES[@]}" $(awk_total <<< "${fls[@]}") )
    unset fls
}
get_menu_titles()
{
    unset y titles
    while [[ $@ ]]; do
        case "$1" in
            "-vmgm")
                while [[ $@ && $1 != "-end-vmgm" ]]; do
                    shift
                done
                ;;
            "-menu-title" )
                shift
                menutitles=("${menutitles[@]}" "$1")
                ;;
            "-titles" )
                shift
                get_listargs "$@"
                OIFS=$IFS
                IFS=""
                vmgmtitles=( "${vmgmtitles[@]}" "${ARGS_ARRAY[@]}" )
                IFS=$OIFS
                ;;
        esac
        shift
    done
}
# used by titleset_mode()
get_titleset_opts()
{
    while test $# -gt 0; do
        case "$1" in
            "-titleset" )
                unset x TSET_OPTS
                shift
                # Hackish list-parsing
                while test $# -gt 0 && test "$1" != "-end-titleset"; do
                    TSET_OPTS[x++]=$1
                    shift
                done
                get_title_count "${TSET_OPTS[@]}"
                ;;
        esac
        shift
    done
}

titleset_mode()
# call todisc recursively in order to allow titlesets
{
    get_titleset_opts "${args[@]}"
    get_menu_titles "${args[@]}"
    ALLTITLES=( ${NUM_TITLES[@]} )
    # get the number of files in each titleset
    num_titles=${NUM_TITLES[@]}
    MENUTITLES=( "${menutitles[@]}" )
    # some vars for vmgm menu, depending on presence of -static or -quick-nav
    # how many titlesets do we have ?
    for i in "$@"; do [[ $i == -end-titleset ]] && ((count++)); done
    VMGM_PAUSE=$PAUSE_TIME
    grep -q  -- -static  <<< "${VMGM_OPTS[@]}" && VMGM_PAUSE="inf"
    for i in ${!VMGM_OPTS[@]}; do
        if [[ ${VMGM_OPTS[i]} = '-loop' ]]; then
            loop_val=${VMGM_OPTS[i+1]}
            test_is_number $loop_val && VMGM_PAUSE=$loop_val
        fi
    done
    # let titlesets know if there is a root menu playall
    get_genopts "${args[@]}" # DEBUG not sure why this was a bad idea before
    if grep -q -- -playall <<< "${VMGM_OPTS[@]} ${GEN_OPTS[@]}"; then
        vmgm_playall="-vmgm_playall"
        VMGM_PLAYALL=:
    fi
    unset vmgmopts tsetopts GEN_OPTS
    DVDAUTHOR_XML="$BASEDIR/dvdauthor.xml"
    VMGM_PRE="        if ( g5 eq 0 ) g5=1;"
    VMGM_PRE="$VMGM_PRE\n        if ( g6 eq 0 ) g6=1; button = g6 * 1024;"
    egrep -qw -- "-switched-menu[s]" <<< "${args[@]}" && \
    VMGM_PRE="$VMGM_PRE\n        if (g1 eq 0) g1=1;"
    $DO_INTRO && INTRO_PRE="        if (g2==1) jump cell 2; "
    $SKIP_VMGM_MENU && VMGM_PRE="$VMGM_PRE\n        if ( g3 eq 0 )  g3=1 ;"
    # make dvdauthor.xml
(
    cat <<EOF
<?xml version="1.0" encoding="utf-8"?>
<dvdauthor dest="$OUT_DIR" jumppad="0">
  <vmgm>
    <menus>
      <video aspect="4:3"/>
      <pgc entry="title">
        <pre>
$(echo -e "$VMGM_PRE")
$(if $QUICK_NAV || $SKIP_VMGM_MENU; then
        for ((i=1; i<=${#TITLESET_OPTS[@]}; i++)); do
            echo -e "        if ( g3 eq $i ) jump titleset $i menu;"
        done
fi)
$(if $VMGM_PLAYALL; then
        # g8 tests if a video finished playing, if not do not jump to next
        echo -e "        if (g8==0) g7=0;" 
        echo -e "        if (g8==1) { " 
        # for a vmgm playall g7 for jumping between titlesets after last video
        for ((i=1; i<=${#TITLESET_OPTS[@]}; i++)); do
            echo -e "          if ( g7 eq $i ) jump titleset $i menu;"
        done
        echo "        }"
        [[ -n $INTRO_PRE ]] && echo "$INTRO_PRE"
fi)
        </pre>
        <post>
$( [[ -n $INTRO ]]  && echo -e "        g2=1; jump vmgm menu entry title;")
        jump cell 1;
        </post>
$(for ((i=1; i<=${#TITLESET_OPTS[@]}; i++)); do
    echo \
    "        <button name=\"$i\">g1=1; g5=1; g6=$i; jump titleset $i menu;</button>"
done)
$(if $VMGM_PLAYALL; then # VMGM playall needs a playall button entry
    pall=$((${#TITLESET_OPTS[@]} + 1))
    # set g8=1 for vmgm playall button even though it means vid finished
    echo -n \
    "        <button name=\"$pall\">g4=1; g7=1; g8=1; jump titleset 1 menu entry root;"
    echo "</button>"
fi)
$(if $QUICK_NAV; then
    echo -e "        <button name=\"ActionLeft\">"
    echo -e "        g5=${ALLTITLES[count-1]}; g3=$count; button=1024;"
    echo -e "        jump vmgm menu entry title;</button>"
    echo -e "        <button name=\"ActionRight\">"
    echo -e "        g5=1; g3=1; button=1024;"
    echo -e "        jump vmgm menu entry title;</button>"
fi)
        $INTRO
        <vob file="$BASEDIR/VMGM.mpg" pause="$VMGM_PAUSE"/>
      </pgc>
    </menus>
  </vmgm>
EOF
) |sed '/^ *$/d' >> "$DVDAUTHOR_XML"
    get_genopts "${args[@]}"

    #################### test for incompatible options #######################
    # this unfortunate block helps user by testing for incompatible options
    # within titlesets, exiting BEFORE having done previous titlesets
    general_options="-no-vmgm -skip-vmgm -out -quick-nav -burn -device
    -speed -no-confirm-backup"
    GREP="egrep -w -q --"
    for opt in $general_options; do
        if $GREP $opt <<< "${tsetopts[@]} ${vmgmopts[@]}" \
                       && ! $GREP $opt <<< "${GEN_OPTS[@]}"; then
            usage_error "$opt is a general option and goes outside of
            '-titleset ... -end-titleset' and '-vmgm ... -end-vmgm' areas"
        fi
    done
    if $GREP -no-vmgm <<< "${GEN_OPTS[@]}" && \
       ! $GREP -quick-nav <<< "${GEN_OPTS[@]}"; then
        usage_error "You can not use -no-vmgm if doing titlesets
             unless using -quick-nav."
    fi
    for t in ${!tsetopts[@]}; do
        options="${tsetopts[t]} ${GEN_OPTS[@]}"
        if $GREP -videos-are-chapters <<< "$options"; then
            if $GREP -playall  <<< "$options"; then
                usage_error \
                 "-videos-are-chapters can not be used with -playall"
            elif $GREP '-group|-slides' <<< "$options"; then
                usage_error "-videos-are-chapters can not be used with
                 grouped videos (-group) or slideshows (-slides)"
            fi
        fi
        # making a static slideshow is incompatible with -quick-menu
        if $GREP -quick-menu <<< "$options" \
         && $GREP -slides <<< "$options" \
         && $GREP -static <<< "$options"; then
            usage_error "A -quick-menu slideshow must be animated.
            If you ARE wanting a static menu, remove the '-quick-menu' option"
        fi
        # warning to backup images if doing slideshow
        if $GREP -slides <<< "$options"; then
            $CONFIRM_BACKUP && confirm_backup
        fi
        # -quick-menu incompatible with -menu-fade
        if $GREP -quick-menu <<< "$options" \
         && $GREP -menu-fade <<< "$options"; then
            usage_error "-quick-menu is incompatible with -menu-fade"
        fi
    done
    unset vmgmtitles
    get_menu_titles "${VMGM_OPTS[@]}"
    if [[ -n ${VMGM_OPTS[@]} ]] && ((${#vmgmtitles[@]} != count)); then
        usage_error "Number of titleset titles must equal the number
         of titlesets. ( -vmgm ... -titles 'Title 1' 'Title 2' -end-vmgm )"
    fi
    ################### end titleset options testing #########################

    if [[ -z ${VMGM_OPTS[@]} ]]; then
        yecho
        yecho "You have not supplied -vmgm OPTIONS -end-vmgm"
        yecho "At a minumum you should have: \
        '-vmgm -titles "Title one" "Title two" -end-vmgm'"
        yecho "One title for each titleset you are making."
        yecho "Any other appropriate todisc options for the vmgm menu \
        can be specified as well."
        if  [[ ${#MENUTITLES[@]} -eq $count ]]; then
            yecho "Since -menu-title was supplied for each titleset: \
            these titleset titles will be used:"
            for t in "${MENUTITLES[@]}"; do echo "\"$t\""; done
            VMGM_OPTS=(-titles "${MENUTITLES[@]}")
        else
            VMGM_OPTS[0]="-titles"
            for ((menu=1; menu<=count; menu++)); do
                VMGM_OPTS[menu]="Titleset $menu"
            done
        fi
        yecho "Making a generic vmgm menu for you - \
        you may wish to cancell out and change this."
        yecho
        $VMGM_MENU && $WARN && sleep 15
    else
        unset vmgmtitles
        get_menu_titles "${VMGM_OPTS[@]}"
        if ((${#vmgmtitles[@]} != 0)) && ((${#vmgmtitles[@]} != count)); then
            usage_error "Number of titleset titles must equal the number
            of titlesets."
        fi
    fi
    ################### end titleset options testing #########################
    # VMGM menu
    yecho
    yecho "Making a VMGM menu with the following command:"
    vmgm_menu_cmd=(todisc "${GEN_OPTS[@]}" -basedir "$WORK_DIR" -vmgm_only \
    -textmenu -todisc_pids "$TODISC_PIDS" $NO_CONFIRM_BACKUP \
    -title_count "$num_titles" $vmgm_playall  "${VMGM_OPTS[@]}")
    yecho "Running: ${vmgm_menu_cmd[@]}"
    INITIALDIR="$BASEDIR"
    if ! "${vmgm_menu_cmd[@]}" ; then cleanup && exit 1; fi
    # TITLESET menus
   # TODO move to function to avoid duplication - generalize for -vmgm too
    while test $# -gt 0; do
        DO_SHIFT=:
        case "$1" in
            "-titleset" )
                let tset=tset+1
                shift
                unset x TITLESET_OPTS
                # Hackish list-parsing
                while test $# -gt 0 && test "$1" != "-end-titleset"; do
                    TITLESET_OPTS[x++]="$1"
                    shift
                done
                titleset_cmd=( todisc -titleset-mode -basedir "$WORK_DIR" \
                -title_count "$num_titles" -tset_num ${count}-${tset} \
                "${GEN_OPTS[@]}" $NO_CONFIRM_BACKUP "${TITLESET_OPTS[@]}" $vmgm_playall )
                yecho
                yecho "Working on the menu for titleset number $tset"
                yecho
                $WARN && sleep 5
                yecho "Running: ${titleset_cmd[@]}"
                if ! "${titleset_cmd[@]}"; then cleanup && exit 1; fi
                yecho
                ;;
        esac
        $DO_SHIFT && shift
    done
    echo -e "</dvdauthor>" >> "$DVDAUTHOR_XML"
    yecho "Running dvdauthor to create final DVD structure"
    dvdauthor -x "$DVDAUTHOR_XML" 2>&1 | tee -a "$LOG_FILE"
    if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
        dvdauthor_error
    fi
    thanks_goodbye
    cleanup

}

parse_rotateargs()
{
    unset x ARGS_ARRAY
    # Hackish list-parsing
    while test $# -gt 0 && egrep -q '^[-+]?[[:digit:]]{1,2}+$' <<< "$1"; do
        ARGS_ARRAY[x++]="$1"
        shift
    done
    # Do not skip past the next argument
    if test $# -gt 0 && test x"${1:0:1}" = x"-";then
        DO_SHIFT=false
    fi
}

burn_disc()
{
    BURN_CMD=(tovid dvd -burn -device "$BURN_DEVICE" $BURN_SPEED \"$BURN_TGT\")
    yecho
    echo "You have indicated you want to burn the $BURN_TGT_STR"
    echo "Would you like to burn the ${BURN_TGT_STR/ *} now ?"
    echo -n "Type 'yes' to continue: "
    read input
    echo
    if [ ! -z "$input" -a "$input" = "yes" ]; then
        echo "Proceeding to burn, continuing."
        echo
        $BURN_PROG -burn -device "$BURN_DEVICE" \
        $BURN_SPEED "$BURN_TGT" | tee -a "$LOG_FILE" 2>&1
        if ((${PIPESTATUS[0]}==0)); then
            echo "Your ${BURN_TGT_STR/ *} should be ready"
        else
            echo "There was a problem burning the ${BURN_TGT_STR/ *}"
            echo "Please see makedvd output above, and "$LOG_FILE" for details"
            echo "When the problem is solved, try again with the command:"
            echo "${BURN_CMD[@]}"
        fi
    else
        echo "Not burning now - please see the parting message from todisc"
        echo "for instructions on using ${BURN_PROG}, or see 'man tovid'"
    fi
}

thanks_goodbye()
{
    echo
    echo $SEPARATOR
    SCRIPT_TIME=$(format_seconds $SECONDS)
    echo "todisc took $SCRIPT_TIME to finish on $CPU_MODEL $CPU_SPEED mhz"
    echo $SEPARATOR
    echo "Your new DVD should be in $OUT_DIR"
    echo "You can preview them in gxine with this command:"
    echo "    gxine \"dvd:/$OUT_DIR\""
    echo "If you are satisfied with the results, you can burn a disc with:"
    echo "    tovid dvd -burn \"$OUT_DIR\""
    echo
    echo "Thanks for using todisc."
}

# usage mk_return_button (mk_play_button) COLOUR1 COLOUR2 OUTBUTTON
# ex. for menu button ( not spumux ):
# mk_return_button "#C6C6C6" black "$WORK_DIR/Main.png"
mk_return_button()
{

    COLR1="$1"
    COLR2="$2"
    TYPE=$3
    OUTBUTTON="$4"
    if [[ $TYPE = "spu" ]]; then
        CLR1="none"
    elif [[ $TYPE = "default" ]]; then
        CLR1="$COLR1"
    fi

    MK_RTN_CMD=(convert -size 100x80 xc:none \
    -strokewidth 1 -stroke "$COLR2" -fill "$CLR1" \
    -draw 'rectangle 0,0 70,62' \
    -fill "$COLR2" -stroke none \
    -draw "polyline 40,10 40,50 10,30 40,10" \
    -draw "polyline 60,10 60,50 30,30 60,10" \
    -fill "$COLR2" -draw "rectangle 6,10 10,50" \
    -resize 30% -trim +repage +antialias "$OUTBUTTON")
    echo -e "\nRunning ${MK_RTN_CMD[@]}\n" |format_output
    "${MK_RTN_CMD[@]}"
    mogrify -channel A -threshold 50% "$OUTBUTTON"
    RTN_BTN_DIM=$(get_image_dim "$OUTBUTTON")
    rtn_btn_width=$(awk -Fx '{print $1}' <<< $RTN_BTN_DIM )
    rtn_btn_height=$(awk -Fx '{print $2}' <<< $RTN_BTN_DIM )
}
mk_play_button()
{
    COLR1="$1"
    COLR2="$2"
    TYPE=$3
    OUTBUTTON="$4"
    if [[ $TYPE = "spu" ]]; then
        CLR1="none"
    elif [[ $TYPE = "default" ]]; then
        CLR1="$COLR1"
    fi
    #-fill "$COLR2" -draw "line 40,10 40,50"  \
    # -fill "$COLR2" -draw "rectangle 36,10 40,50" \
    MK_PLAY_CMD=(convert +antialias -size 100x80 xc:none  \
    -strokewidth 2 -stroke "$COLR2" -fill "$CLR1" \
    -draw 'rectangle 22,0 92,62' \
    -fill "$COLR2" -stroke none \
    -draw "polyline 40,10 40,50 80,30 40,10" \
    -resize 30% -trim +repage "$OUTBUTTON")
    echo -e "\nRunning ${MK_PLAY_CMD[@]}\n" |format_output >> "$LOG_FILE"
    "${MK_PLAY_CMD[@]}"
    PLAY_BTN_DIM=$(get_image_dim "$OUTBUTTON")
    play_btn_width=$(awk -Fx '{print $1}' <<< $PLAY_BTN_DIM )
    play_btn_height=$(awk -Fx '{print $2}' <<< $PLAY_BTN_DIM )
}

check_menufile()
{
    yecho
    if test -f "$MENU_FILE"; then
        echo "Menu file $MENU_FILE created"
        echo
    else
        runtime_error "Menu file $MENU_FILE not found.  \
        Spumux seems to have had problems"
    fi
}

quick_menu()
{
    unset LEFTPAD TOPPAD RIGHTPAD BOTTOMPAD
    # get width and height of background: we may need to resize it to $VIDSIZE
    if $QUICKMENU_IS_BACKGROUND; then
        BG_VIDEO_STATS=$(idvid -fast "$BG_VIDEO" 2>/dev/null)
        BG_VIDEO_WIDTH=$(awk '/Width:/ {print $2}' <<< "$BG_VIDEO_STATS")
        BG_VIDEO_HEIGHT=$(awk '/Height:/ {print $2}' <<< "$BG_VIDEO_STATS")
        if [[ ${BG_VIDEO_WIDTH}x${BG_VIDEO_HEIGHT} != $VIDSIZE ]]; then
            RESIZE_BG=:
        fi
    fi
    if [[ -n $1 && $1 = "preview" ]]; then
        QM_MENU_TIME=2 && QM_PREVIEW=:
    else
        QM_MENU_TIME=${MENU_LEN[MENU_NUM-1]} && QM_PREVIEW=false
    fi
    # if QUICK_MENU_FILE is a showcase video then we need a temp avi file
    if $QUICKMENU_IS_SHOWCASE; then
        PRE_VHOOK_FILE="$WORK_DIR/quick_tmp.avi" # not needed for mix
        outdir="$WORK_DIR/showcase"
        if $SWITCHED; then
            qm_seek="-ss ${SEEK_VAL[MENU_NUM-1]}"
        else
            qm_seek="-ss $SHOWCASE_SEEK_VAL"
        fi
    # else if we have background file maybe no need for the 1st resize step
    elif $QUICKMENU_IS_BACKGROUND; then
        if ! $RESIZE_BG; then
            PRE_VHOOK_FILE="$BG_VIDEO"
        else
            PRE_VHOOK_FILE="$WORK_DIR/quick_tmp.avi"
        fi
        outdir="$WORK_DIR/bg"
        qm_seek="-ss $BG_SEEK"
    fi
    # find out where vhook lives for ffmpeg
    ffmpeg_prefix=$(which ffmpeg)
    ffmpeg_prefix=$(sed 's/\/bin\/ffmpeg//g' <<< "$ffmpeg_prefix")
    imlib2_vhook="$ffmpeg_prefix/lib/vhook/imlib2.so"

    # check for badly compiled or otherwise unusable vhook
    if $QM_PREVIEW && [[ $MENU_NUM -eq $MN ]]; then
        ! [[ -s "$imlib2_vhook" ]] && runtime_error "Missing ffmpeg's vhook's"
        yecho
        yecho "Making a MPEG for testing ffmpeg's imlib2 vhook"
        convert  -resize $VIDSIZE! xc:"#101010" "$WORK_DIR/dummy.jpg"
        dummy_cmd=(ffmpeg -t 2 -loop_input -i "$WORK_DIR/dummy.jpg" \
        -aspect 4:3  -f mpeg1video -r 29.970 -vcodec mpeg2video -b 5000k \
        -f s16le  -i /dev/zero -acodec ac3 -ac 2 -ar 48000 -ab 224k \
        -y "$WORK_DIR/dummy.mpg")
        if ! "${dummy_cmd[@]}" 2>> "$LOG_FILE"; then
            runtime_error "There was a problem making a dummy.mpg with ffmpeg"
        fi
        if ! ffmpeg -vhook "$imlib2_vhook -i "$WORK_DIR/dummy.jpg"" \
        -i "$WORK_DIR/dummy.mpg" -y "$WORK_DIR/test.mpg" 2>> "$LOG_FILE"; then
            runtime_error "Your ffmpeg's vhook is broken.  No 'quick-menu' :("
        fi
        yecho
    fi
    $QM_PREVIEW && yecho "Creating a quick-menu preview image"
    # convert and resize the bgvideo so that is is framed by ntsc-safe black bg
    if $QUICKMENU_IS_SHOWCASE || $RESIZE_BG; then
        yecho
        if $RESIZE_BG; then
            yecho "resizing background video: $BG_VIDEO"
            QM_TMP_FRAMESIZE=$VIDSIZE
        else
            yecho "resizing and padding showcase file: $SHOWCASE_VIDEO"
            LEFTPAD=$SC_X
            TOPPAD=$SC_Y
            RIGHTPAD="-padright \
            $(( ${VIDSIZE%%x*} - $LEFTPAD - ${SHOWCASE_SIZE%%x*} ))"
            BOTTOMPAD="-padbottom \
            $(( ${VIDSIZE##*x} - $TOPPAD - ${SHOWCASE_SIZE##*x} ))"
            LEFTPAD="-padleft $SC_X"
            TOPPAD="-padtop $SC_Y"
            QM_TMP_FRAMESIZE=$SHOWCASE_SIZE
        fi
        PAD_CMD=(ffmpeg -r $FRAME_RATE -async 1 $qm_seek \
        -t "$QM_MENU_TIME" -i "$QUICK_MENU_FILE" -s $QM_TMP_FRAMESIZE \
        -acodec copy $TOPPAD $BOTTOMPAD $LEFTPAD $RIGHTPAD \
        -r $FRAME_RATE -b 15000k -padcolor $BG_CLR \
        -y  "$WORK_DIR/quick_tmp.avi")
        yecho
        yecho "Running ${PAD_CMD[@]}"|fold -bs
        "${PAD_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"
    fi

    # use vhook to add the titles in
    ! $QM_PREVIEW && yecho
    if ! $QM_PREVIEW; then
        yecho "Using ffmpeg's vhook to add titles and background"
    fi
    # don't seek if we already made a padded video with a seek
    $QUICKMENU_IS_SHOWCASE || $RESIZE_BG && qm_seek=""
    VHOOK_CMD=(ffmpeg -t "$QM_MENU_TIME" $qm_seek -s $VIDSIZE -i  \
    "$PRE_VHOOK_FILE" -an -f mpeg2video -r $FRAME_RATE -tvstd $TV_STANDARD \
    -b 7000k -maxrate 8000k -bufsize 224KiB -aspect 4:3 \
    -vhook "$imlib2_vhook -x 0 -y 0 -i $WORK_DIR/quick_menu_bg.png" \
    -y "$WORK_DIR/intro.m2v")
    $QM_PREVIEW && yecho
    $QM_PREVIEW && yecho "Running ${VHOOK_CMD[@]}" | fold -bs
    "${VHOOK_CMD[@]}" 2>&1 | strings >> "$LOG_FILE"
    ! $QM_PREVIEW && yecho
    # create preview images if called for
    if $QM_PREVIEW; then
        FFMPEG_CMD=(ffmpeg -ss 1 -i "$WORK_DIR/intro.m2v" -an -vframes 30 \
        "$outdir"/%06d.png)
        yecho "${FFMPEG_CMD[@]}" | strings
        "${FFMPEG_CMD[@]}" 2>&1 | strings >> "$LOG_FILE"
        largest_png=$(du -s "$outdir"/*.png|sort -r |
        awk 'NR>1{exit};1 {print $2}')
        mv "$largest_png" "$PREVIEW_IMG"
        yecho "Removing temporary preview files"
        rm -f "$WORK_DIR/intro.m2v"
        $QUICKMENU_IS_SHOWCASE && rm -f "$WORK_DIR/quick_tmp.avi" \
        "$WORK_DIR"/showcase/*.png
        $QUICKMENU_IS_BACKGROUND && rm -f  "$WORK_DIR"/bg/*.png
    fi
    $QM_PREVIEW && yecho
}

# 3x1 and 4x1 tile only for default arrangement
tile_warning()
{
    yecho
    echo "-tile-3x1 and -tile-4x1 are not showcase options.  Disabling"
    yecho
    $WARN && sleep 5
}
dvdauthor_error()
{
    echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    yecho "todisc encountered an error:"
    yecho "There was a problem creating the DVD structure"
    yecho "Saving files in "$WORK_DIR" so you can examine the situtaion"
    yecho "You can edit "$WORK_DIR/dvdauthor.xml" and rerun: "
    yecho "dvdauthor -x dvdauthor.xml from inside $REAL_WORK_DIR"
    yecho "Remove the symlink in /tmp when you are done"
    echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    exit 1
}

confirm_backup()
{
    yecho
    yecho "Slideshows are an experimental (but well tested) feature.  Todisc is
    unlikely to overwrite your personal files, but you should take precautions
    and backup your images/files, as you would with any beta software."
    yecho "You can disable the check by using '-no-confirm-backup'"
    echo
    yecho "If and when you have backed up your images, type 'yes' to continue"
    read input
    echo
    if [ ! -z "$input" -a "$input" = "yes" ]; then
        CONFIRM_BACKUP=false
        NO_CONFIRM_BACKUP="-no-confirm-backup"
        yecho "Continuing..."
        yecho
    else
        yecho "Exiting..."
        yecho
        cleanup
        exit 0
    fi
}

make_dummy()
{
    yecho "Creating a blank mpeg for the vmgm menu"
    convert  -resize $VIDSIZE! xc:"#101010" "$WORK_DIR/dummy.jpg"
    ENC_CMD1=(jpeg2yuv -v 1 -f $FRAME_RATE -I p -n 1 -l 30 -L 1 -b1 \
    -j "$WORK_DIR/dummy.jpg")
    ENC_CMD2=(ffmpeg -f yuv4mpegpipe -i - -an -r $FRAME_RATE -s $VIDSIZE \
    -tvstd $TV_STANDARD $FFMPEG_OPTS -y "$WORK_DIR/dummy.m2v")
    echo "Running: ${ENC_CMD1[@]} | ${ENC_CMD2[@]}" |
    format_output | tee -a "$LOG_FILE"
    if ! ${ENC_CMD1[@]} 2>> "$LOG_FILE"  |
    ${ENC_CMD2[@]} 2>&1 |strings  >> "$LOG_FILE"; then
        runtime_error
    fi
    VMGM_TIME=$(vid_length "$WORK_DIR/dummy.m2v")
    yecho
    # temporarily use mp2enc for svcd audio as ffmpeg broken # FIXME
    # see r2162 todisc or older for how to fix this block when ffmpeg is fixed
    BGAUDIO_CMD=(ffmpeg -f s16le -i /dev/zero -t $VMGM_TIME \
    $AUDIO_OPTS -y "$WORK_DIR/dummy.$AUDIO_EXT")
    yecho "${BGAUDIO_CMD[@]}"
    "${BGAUDIO_CMD[@]}" 2>&1 | strings >> "$LOG_FILE"
    ! [[ -s "$WORK_DIR/dummy.$AUDIO_EXT" ]] &&  runtime_error

    MPLEX_CMD=(mplex -V -f $MPLEX_FORMAT -o  "$BASEDIR/dummy.mpg" \
     "$WORK_DIR/dummy.$AUDIO_EXT"  "$WORK_DIR/dummy.m2v")
    echo "Running: ${MPLEX_CMD[@]}" |fold -bs >> "$LOG_FILE"
    ! "${MPLEX_CMD[@]}" 2>&1 |strings >> "$LOG_FILE" && runtime_error
}
verify_infiles()
{
    # OUTFILE is $WORK_DIR/(basename of file without extension)
    verify_type=$1
    if [[ $verify_type = "infiles" ]]; then
        in_files=( "${IN_FILES[@]}" )
    else
        for f in ${!grouping[@]}; do
                in_files[f]=$(readlink -f "${grouping[f]}")
        done
    fi
    for ((i=0; i<${#in_files[@]}; i++)); do
        CROP_CMD=()
        IN_FILE="${in_files[i]}"
        if test -s "$IN_FILE"; then
            check_filetype "$IN_FILE"
            if [[ $TYPE = "image" ]]; then
                IMG_STATS=( $(identify -ping -format "%z %w %h" "$IN_FILE") )
                DEPTH=${IMG_STATS[0]}
                IMG_WIDTH=${IMG_STATS[1]}
                IMG_HEIGHT=${IMG_STATS[2]}
                IMG_AR=$(bc_math "$IMG_WIDTH / $IMG_HEIGHT")
                if [[ $ASPECT_RATIO = "4:3" ]]; then
                    NEWSIZE=640x480
                else
                    NEWSIZE=640x360
                fi
                if [[ ${IMG_AR:0:4} != ${AR:0:4} ]]; then
                    CROP_CMD=(-resize  ${NEWSIZE}\> -size $NEWSIZE \
                    xc:'#101010' +swap -gravity center -composite)
                    PAD_IMG="yes"
                else
                    CROP_CMD=(-resize 640x480\!)
                fi
                OUTBASE=${IN_FILE##*/} # basename of file
                OUTFILE=${OUTBASE%.*} # basename of file less extention
                OUTFILE_GRP=${grouping[i]##*/} # basename of link
                OUTFILE_GRP=$OUTFILE_GRP%.*} # basename of link less extension
                OUTFILE_GRP=$(cut -f3-4 -d- <<< "$OUTFILE_GRP")
                OUTFILE_GRP=$(cut -f 1 -d. <<< "$OUTFILE_GRP") # group number
                if [[ $verify_type = "group" ]]; then
                    OUTFILE="$WORK_DIR/${TSET_NUM}-${OUTFILE_GRP}-${OUTFILE}"
                else
                    OUTFILE="$WORK_DIR/${TSET_NUM}-${i}-${OUTFILE}"
                fi
                OUTPNG="${OUTFILE}.png"
                # ffmpeg image2 can't handle 16 bit depth - convert it
                # also convert if not PNG or JPEG or wrong aspect ratio
                # test IN_FILES for preview - group files tested later
                if [[ $DEPTH = 16 || $PAD_IMG = "yes" ]] || $CONVRT ; then
                    echo "Converting $IN_FILE to proper image format" \
                      >> "$LOG_FILE"
                    IMG_CMD=(convert "$IN_FILE" -depth 8 "${CROP_CMD[@]}" \
                    -quality 01 "$OUTPNG")
                    format_output <<< "${IMG_CMD[@]}" \
                        >> "LOG_FILE"
                    "${IMG_CMD[@]}" |format_output >> "$LOG_FILE" 2>&1
                    # replace IN_FILES[i] OR group symlink
                    if [[ $verify_type = "infiles" ]]; then
                        IN_FILES[i]=$OUTPNG
                    else # this symlink gets replaced with the mpeg later
                        if [[ -L ${grouping[i]} ]]; then
                            png_out="${grouping[i]##*/}"
                            ln -sf "$OUTPNG" "$WORK_DIR/$png_out"
                            # replace saved link to original file too
                            ln -sf "$OUTPNG" \
                            "$WORK_DIR/${png_out/group/slide_grp}"
                        fi
                    fi
                fi
                if [[ $verify_type = "infiles" ]]; then
                    if [[ "$SC_FRAMESTYLE" = "glass" ]]; then
                        # make mpeg with ffmpeg now since OUTFILE is a link
                        image2mpeg2 "${IN_FILES[i]}" \
                        "$WORK_DIR/${OUTFILE##*/}.mpg"
                        # replace IN_FILE link with actual new file
                        IN_FILES[i]=$WORK_DIR/${OUTFILE##*/}.mpg
                    else
                        file_is_image[i]="yes" # encode to mpeg later
                    fi
                else
                    grp_file_is_image[i]="yes"
                fi
                spin checking "${IN_FILE##*/}"
            elif mencoder -quiet -oac pcm -ovc copy \
            -frames 0 -o /dev/null "$IN_FILE" &>/dev/null; then
                checkfile="${IN_FILE##*/}"
                spin checking "$checkfile"
            else
                usage_error "Sorry, $IN_FILE is not a supported file type"
            fi
        else
            usage_error "Sorry, $IN_FILE does not exist or is empty"
        fi
    done
}

# contrasting 'undercolor' for -background from given font colour
# usage: get_contrasting_colour COLOUR (rgb , named, or hex syntax)
get_contrasting_color()
{
    ucolor=$(convert -size 20x20 xc:$1 -fx 1-intensity -threshold 50% \
    -depth 8 txt:- 2>/dev/null |  awk '{ field = $NF }; END{ print field }')
    if [[ -z $ucolor ]]; then
        CONTRAST_CLR="none"
    else
        if [[ $ucolor = "black" ]]; then
            CONTRAST_CLR="#101010"
        else
            CONTRAST_CLR="gray"
        fi
    fi
}

# get safe NTSC colour
get_safe_colour()
{
    unset SAFE_CLR
    if [[ $1 ]]; then
        case $1 in
            '#ffffff'|'#FFFFFF'|white) SAFE_CLR='#EAEAEA' && \
              SUB_CLRS+=( "${1}:${SAFE_CLR}" );;
            '#000000'|black) SAFE_CLR='#101010' && \
              SUB_CLRS+=( "${1}:${SAFE_CLR}" );;
            '#FF0000'|'#ff0000'|red) SAFE_CLR='#EB2D2D' && \
              SUB_CLRS+=( "${1}:${SAFE_CLR}" );;
            '#FFFF00'|'#ffff00'|yellow) SAFE_CLR='#EBEB2D' && \
              SUB_CLRS+=( "${1}:${SAFE_CLR}" );;
            '#0000FF'|'#0000ff'|blue) SAFE_CLR='#2D2DEB' && \
              SUB_CLRS+=( "${1}:${SAFE_CLR}" );;
            *) return 1
        esac
    fi
}

# see http://www.imagemagick.org/Usage/photos/#binning
# the function is modified from a script by Walter Dnes with thanks
get_binning_cmd()
{
    ind=$1
    inpic="$2"; outpic="$WORK_DIR/${ind}.ppm"
    dimensions=$(identify -ping -format %wx%h "$inpic")
    x=${dimensions/x*}
    y=${dimensions/*x}
    # only do binning resize if doing 'full screen' and image width is > 1440
    # and user did not ask specifically not to
    if { ((x>1440)) || ((y>1440)) ; } && \
     $DO_BINNING && (( ${CAROUSEL_SIZE/x*} > 400 )); then
        for bin_size in 1 2 3 4 5 6 7 8; do
            newx=$(( x / bin_size ))
            # ppmtoy4m needs a multiple of 2 (hopefully doesn't affect binning)
            newx=$(( (newx / 2) * 2 ))
            ((newx<=BINMAX)) && break
        done
    else
        return 0
    fi

    checkx=$(( newx * bin_size ))
    (( checkx != x )) && crop_flag="YES"

    newy=$(( y / bin_size ))
    newy=$(( (newy / 2) * 2 )) # must be multiple of 2 for ppmtoy4m
    checky=$(( newy * bin_size ))
    (( checky != y )) && crop_flag="YES"

    [[ -n $crop_flag ]] && crop_args="-crop ${checkx}x${checky}+0+0 +repage"
    unset PPM_ENC_CMD
    BINNING_CMD=(convert "$inpic" $crop_args -depth 8 \
    -filter box -resize ${newx}x${newy} ${SLIDE_BLUR[p]} "$outpic")
}

# make dvd-slideshow config file if using -use-dvd-slideshow
mk_dvd_slideshow_conf()
{
    if $SLIDE_FADE; then
        [[ $EFFECT = "fade" ]] && fadein=fadein:1 && fadeout=fadeout:1
        [[ $EFFECT = "crossfade" ]] && crossfade=crossfade:1
    fi
    (
    cat <<EOF
    fadein:1
    $(for i in ${!MIX_IN[@]}; do
        echo $fadein
        echo ${MIX_IN[i]}:$MIX_SLIDE_LEN
        if (( i < (${#MIX_IN[@]} - 1) )); then
            [[ $EFFECT = "crossfade" ]] && echo $crossfade
            echo $fadeout
        fi
    done)
    fadeout:1
EOF
    ) | sed '/^$/d;s/^[ \t]*//' > "$WORK_DIR/dvd-slideshow.conf"
}

transition_slide()
{
    TYPE=$1
    index=$2
    outppm="$WORK_DIR/animenu/$(printf %06d%s $index .ppm)"
    if [[ $TYPE = "crossfade" ]]; then
        local VALUE=$(bc -l <<< "scale=2; ($fade_slide + 1) * $fade_incr") >&2
        fade_cmd=(composite -blend $VALUE -depth 8 "$overlay_ppm" \
        "$base_ppm" "$outppm")
    elif [[ $TYPE = "fadein" ]]; then
        local VALUE=$(bc -l <<< "scale=2; $fade_slide * $fade_incr") >&2
        fade_cmd=(composite -depth 8 "$base_ppm" "$WORK_DIR/black.ppm" \
        -blend ${VALUE}% "$outppm")
    elif [[ $TYPE = "fadeout" ]]; then
        local VALUE=$(bc -l <<< "scale=2;100 - (($fade_slide + 1) * $fade_incr)") >&2
        (( $(bc <<< "$VALUE < 0") == 1 )) && local VALUE=0
        fade_cmd=(composite -depth 8 "$base_ppm" "$WORK_DIR/black.ppm" \
        -blend ${VALUE}% "$outppm")
    fi
     "${fade_cmd[@]}" >/dev/null
}

# this function does a loop with transition_slide() ... combine them into 1 ?
do_transitions()
{
    TYPE=$1
    fade_slide=0
    for ((i=0; i<=fade_frames; i++)); do
        transition_slide $TYPE $i &
        transition_pids="$transition_pids $!"
        ((num_procs++))
        if ((num_procs == max_procs || i == fade_frames-1)); then
            wait $transition_pids
            unset transition_pids num_procs
        fi
        let fade_slide=fade_slide+1
    done
    if [[ $TYPE = "fadeout" ]] && ((f == ${#MIX_IN[@]}-1)); then
        for p in {0..12}; do
            cp "$WORK_DIR/black.ppm" \
            "$WORK_DIR/animenu/$(printf %06d%s $((p +i)) .ppm)" >&2
        done
    fi
}

# border and/or frame slides
border_and_frame()
{
    SLIDE_IN="$1"
    SLIDE_OUT="$2"
    convert  -size 640x480 "$SLIDE_IN" -mattecolor $SFRAME_CLR \
    -thumbnail ${tmbnail_size}\> $SLIDE_FRAME $SLD_BG +swap -gravity center \
    -composite "$SLIDE_OUT"
}

mk_polaroid_stack()
{
    local stackfiles=( "$@" )
    local CONVERT="convert -quality 01 -depth 8"
    local TSIZE=120x80
    local CANVAS_SIZE=640x480
    local rand_xmax=400
    local rand_ymax=200
    local rand_xoffset=80
    local rans_yoffset=50

    # this assignment not used in script, just for standalone demo purposes

    for i in ${!stackfiles[@]}; do

        # Use a 'random' angle
        local angle=$((RANDOM %45 +1))
        local angle=$(( (angle / 2) * 2 ))
        # use a 'random' direction of rotation
        #local rand_dir=$((RANDOM %2))
        #((rand_dir==0)) && randir="" || randir='-'
        rand_dir=""
        # thumbnail to 120x80 or 80x80 # TODO get working for pal
        $CONVERT "${stackfiles[i]}" -background none -thumbnail ${TSIZE}! \
        -bordercolor '#EAEAEA' -shave 5x5 +repage -border 4x4 \
        -bordercolor grey60 -border 1 \
        -rotate ${randir}${angle}  \
        -background  black  \( +clone -shadow 60x4+4+4 \) +swap \
        -background  none   -flatten \
        "$WORK_DIR/tnail${i%.*}.png"
        stack_files[i]=$WORK_DIR/tnail${i%.*}.png

        # Composite the polaroid over the canvas

        # get 'random' coordinates
        local rand_xloc=$((RANDOM %rand_xmax + rand_xoffset))
        local rand_yloc=$((RANDOM %rand_ymax + rans_yoffset))
        local rand_loc="+${rand_xloc}+${rand_yloc}"
        local img_page[i]="-page $rand_loc"
    done
    for i in ${!stack_files[@]}; do
        local \
        image_page=( "${image_page[@]}" ${img_page[i]} "${stack_files[i]}" )
    done
    $CONVERT -background none -size $CANVAS_SIZE xc:none \
    "${image_page[@]}" -mosaic -trim +repage "$WORK_DIR/polaroid_stack.png"
}

get_elapsed()
{
    echo -e "\nIt took $(format_seconds $((etime-stime)) ) for the $1\n"
}
# make sure  correct sample size option for sox  is used
# getting sox version is inconsistent, so just run test command
get_sox_arg()
{
if cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 -w -s - \
"$WORK_DIR/foo.wav" trim 0 1 &>/dev/null; then
    echo -w
elif cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 -2 -s - \
"$WORK_DIR/foo.wav" trim 0 1 &>/dev/null; then
    echo -2
else
    runtime_error "Your sox appears to be incompatible with this program.  " \
    "Attempted to create a wav file using the -w option, then the -2 option"
fi
rm -f "$WORK_DIR/foo.wav"

}

# Usage: check_maskshape SHAPE.  Returns 1 if SHAPE not found.
check_maskshape()
{
    SHAPE="$1"
    ! egrep -q -w \
    'oval|vignette|plectrum|flare|arch|spiral|blob|star|normal' \
    <<< "$SHAPE"  && \
    ! test -f "$TOVID_PREFIX/masks/${SHAPE}.png" && \
    ! test -f "$HOME/.tovid/masks/$SHAPE.png" 
    (($? == 0)) && return 1 || return 0
}

# make an image mask for feathered shapes
# usage: make_mask SHAPE thumb|showcase
make_mask()
{
    local shape="$1"
    local mask_type="$2"
    if [[ $mask_type == "thumb" ]]; then
        local BLUR_CMD=( "${THUMB_BLUR_CMD[@]}" )
    else
        local BLUR_CMD=( "${SC_BLUR_CMD[@]]}" )
    fi
    MASK="$WORK_DIR/${shape}_${mask_type}_mask.png"

    case "$shape" in
      "normal")
        convert -size $THUMB_SIZE xc:black -fill white \
        -draw "Rectangle $MASK_DIM" \
        +matte -compose CopyOpacity miff:- |
        convert - -bordercolor none -border 8x8 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      "oval")
        convert -size $THUMB_SIZE xc:black -fill white \
        -draw "RoundRectangle $DIMY1,$DIMY1 $DIMY2,$DIMX2, $DIMY3,$DIMX3" \
        +matte -compose CopyOpacity miff:- |
        convert - -bordercolor none -border 6x6 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      "vignette")
        convert -size 200x200 xc:white -background black -vignette 0x8 miff:- |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      "flare")
        # with thanks to Fred Weinhaus for his starburst script and
        # Anthony Thyssen who did the original investigation of the technique
        # http://www.imagemagick.org/Usage/advanced/#radial_flares
        # test if imagemagick has -distort polar
        if ! convert -list distort | grep -q -w Polar; then
            usage_error "Your imagemagick version is too old to support the
              \"-distort polar\" technique used with the 'flare' thumb 
              shape.  Upgrade your imagemagick to version 6.3.5-1 or
              newer, or use a different thumb shape."
        fi
        convert -size 200x1 xc: -seed 100 +noise Random -channel G -separate \
        +channel +level-colors black,white -size 200x199 xc:black -append \
        -motion-blur 66x65535-90 \( -size 200x132  gradient:white-black \
        -evaluate cos .5 -negate -evaluate pow 1.5 \) -compose screen \
        -composite -distort Polar -1 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert \( -size 200x200 xc:black \) \( - -level 0,100%  \) \
        -geometry +0+0 -composite miff:- |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      "plectrum")
        convert -size 200x200 xc:none -fill white \
        -draw 'circle 100,100 150,150' miff:- |
        convert -background none -wave -50x456 - miff:- |
        convert - -bordercolor none -border 3x3 -trim +repage miff:- |
        convert - -bordercolor none -border 18x18 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      "arch")
        convert -size 200x200 xc:none -fill white \
        -draw 'circle 25,30 10,30' -draw 'circle 25,170 10,170' \
        -draw 'circle 175,30 160,30' -draw 'circle 175,170 160,170' \
        -draw 'rectangle 25,15 180,185' -draw 'rectangle 10,25 190,175' miff:- |
        convert -background none -wave -50x456 - miff:- |
        convert - -bordercolor none -border 3x3 -trim +repage miff:- |
        convert - -bordercolor none -border 18x18 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      "spiral")
        convert -size 200x200 xc:none -fill white \
        -draw 'circle 65,100 100,150' -draw 'circle 135,100 100,150' \
        -draw 'rectangle 60,38 140,162'  miff:-  |
        convert -background none -wave -80x188 - miff:- |
        convert -background none -swirl 1440 - miff:- |
        convert - -bordercolor none -border 3x3 -trim +repage miff:- |
        convert - -bordercolor none -border 18x18 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      "star")
        convert -size 290x200 xc:none -fill white \
        -draw  "polygon 75,37.5  89.5,80.5 134.5,80.5 98.5,107.5 111.5,150.5 \
        75,125    38.5,150.5   51.5,107.5 15.5,80.5    60.5,80.5" miff:- |
        convert - -trim +repage miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK
        ;;    
      "blob")
        echo $SEPARATOR
        echo "Running convert -size 100x60 xc:none -fill white \
        -draw \"circle 41,39 44,57 circle 59,39 56,57 circle 50,21 50,3\" miff:- |
        convert - -trim +repage -bordercolor none -border 10x10 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK" | format_output
        echo $SEPARATOR

        convert -size 100x60 xc:none -fill white \
        -draw "circle 41,39 44,57 circle 59,39 56,57 circle 50,21 50,3" miff:- |
        convert - -trim +repage -bordercolor none -border 10x10 miff:- |
        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
        convert - -resize $THUMB_SIZE! $MASK
        ;;
      *)
        if test -f "$HOME/.tovid/masks/$shape.png"; then
            convert "$HOME/.tovid/masks/$shape.png" \
            -bordercolor none -border 3x3 -trim +repage miff:- |
            convert - -bordercolor none -border 18x18 miff:- |
            ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
            convert - -resize $THUMB_SIZE! $MASK

        elif test -f "$TOVID_PREFIX/masks/$shape.png"; then
            convert "$TOVID_PREFIX/masks/$shape.png" \
            -bordercolor none -border 3x3 -trim +repage miff:- |
            convert - -bordercolor none -border 18x18 miff:- |
            ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
            convert - -resize $THUMB_SIZE! $MASK
        fi
        ;;
    esac
}
##############################################################################
#                          	 End of Functions                                #
##############################################################################


trap 'cleanup; exit 13' TERM INT

# ***********************************
# EXECUTION BEGINS HERE
# ***********************************

###############################################################################
#       Process arguments to the script, set up VARS and WORK_DIR             #
###############################################################################

# if -prefix is passed, show the prefix and exit
[[ ${args[0]} == '-prefix' ]] && echo $TOVID_PREFIX && exit 0

egrep -q 'titleset-mode|switched-mode|menu-only|carousel_menu_mode' <<< "$@" \
 && NONAME=:
! $NONAME && yecho $"$SCRIPT_NAME"

while test $# -gt 0; do
    DO_SHIFT=:
    case "$1" in
        "-files" | "-slides" )
            unset sshows inc_files unset grp
            if [[ $1 = '-files' ]]; then
                incoming_vids=:; incoming_slides=false
            else
                incoming_vids=false; incoming_slides=:
            fi
            for i in ${args[@]}; do
                [[ $i = -slides  ]] && ((sshows++))
                [[ $i = -files ]] && ((inc_files++))
            done
            ((sshows==1)) && ((inc_files<1)) && SINGLE_SLIDESHOW=:
            shift
            get_listargs "$@"
            if $incoming_vids || [[ $sshows -eq 1 && $inc_files -lt 1 ]]; then
                for f in  ${!ARGS_ARRAY[@]}; do
                    FILENAMES[f]=${ARGS_ARRAY[f]}
                    filenames[f]=$(readlink -f "${ARGS_ARRAY[f]}")
                done
                if $incoming_slides; then
                    SLIDESHOW=( ${SLIDESHOW[@]} : ) # is this a slideshow ?
                else
                    for f in ${!ARGS_ARRAY[@]}; do
                        SLIDESHOW=( "${SLIDESHOW[@]}" false )
                    done
                fi
                FILES=( "${FILES[@]}" "${filenames[@]}" )
            else
                ((num_slideshows++))
                ! $GROUPING && mk_workdir
                unset group groupkey grp x
                for ((i=0; i<${#ARGS_ARRAY[@]}; i++)); do
                    grp[x++]=$(readlink -f "${ARGS_ARRAY[i]}")
                done
                unset x
                [[ -z ${FILES[@]} ]] && ss_index=0 || ss_index=${#FILES[@]}
                SLIDESHOW[ss_index]=: # is this a slideshow ?
                FILES[ss_index]=$(readlink -f "${ARGS_ARRAY[0]}")
                GROUP_IN_FILES=( "${GROUP_IN_FILES[@]}" "${grp[@]}" )
                groupkey=${#FILES[@]}
                GROUP[groupkey-1]=${#grp[@]}
                ((groupkeys++))
                # create symlinks to ease substitution later
                for c in ${!grp[@]}; do
                    ln -s "${grp[c]}" \
                     "$WORK_DIR/${TSET_NUM}-group-$((groupkey))-$((c+1)).mpg"
                    # keep track of original images as above is overwritten
                    ln -s "${grp[c]}" \
                     "$WORK_DIR/${TSET_NUM}-slide_grp-$((groupkey))-$((c+1)).mpg"
                done
                GROUPING=:
            fi
            ;;
        "-titleset" )
            shift
            unset x ARGS_ARRAY
            while test $# -gt 0 && test "$1" != "-end-titleset"; do shift ; done
            if test $# -gt 0 && test x"${1:0:1}" = x"-";then DO_SHIFT=false; fi
            TITLESET_OPTS[y++]=${ARGS_ARRAY[@]}
            DO_TITLESETS=:
            ;;
       "-vmgm" )
            shift
            unset x ARGS_ARRAY
            # Hackish list-parsing
            while test $# -gt 0 && test "$1" != "-end-vmgm"; do
                ARGS_ARRAY[x++]="$1"
                shift
            done
            # Do not skip past the next argument
            if test $# -gt 0 && test x"${1:0:1}" = x"-";then
                DO_SHIFT=false
            fi
            VMGM_OPTS=( "${ARGS_ARRAY[@]}" )
            ;;
        "-group" )
            shift
            ! $GROUPING && mk_workdir
            get_listargs "$@"
            unset group groupkey grp x
            for ((i=1; i<${#ARGS_ARRAY[@]}; i++)); do
                grp[x++]=$(readlink -f "${ARGS_ARRAY[i]}")
            done
            GROUP_IN_FILES=( "${GROUP_IN_FILES[@]}" "${grp[@]}" )
            ((${ARGS_ARRAY[0]})) 2>/dev/null || usage_error "Arguments to \
            -group must be preceeded by a positive integer.  See 'man tovid'"
            groupkey=$(( ${ARGS_ARRAY[0]} - 1))
            GROUP[groupkey]=${#grp[@]}
            # temporary till I finish submenu groups TODO
            is_vidgroup[groupkey]=1
            # create symlinks to ease substitution later
            for c in ${!grp[@]}; do
                ln -s "${grp[c]}" \
                $WORK_DIR/${TSET_NUM}-group-$((groupkey+1))-$((c+1)).mpg
            done
            GROUPING=:
            ;;
        "-titles" )
            shift
            get_listargs "$@"
            OIFS=$IFS
            IFS=""
            TITLES=( "${TITLES[@]}" "${ARGS_ARRAY[@]}" )
            IFS=$OIFS
            ;;
        "-chapter-titles" )
            shift
            get_listargs "$@"
            OIFS=$IFS
            IFS=""
            for c in ${!ARGS_ARRAY[@]}; do
                CHAPTER_TITLES=("${CHAPTER_TITLES[@]}" "${ARGS_ARRAY[c]}")
            done
            IFS=$OIFS
            ;;
        "-slideshow-menu-thumbs" )
            shift
            get_listargs "$@"
            for f in  ${!ARGS_ARRAY[@]}; do
                SLIDESHOW_MENU_THUMBS[f]=$(readlink -f "${ARGS_ARRAY[f]}")
            done
            ;;
        "-submenu-titles" )
            shift
            get_listargs "$@"
            OIFS=$IFS;IFS=""
            SM_TITLES=( "${ARGS_ARRAY[@]}" )
            IFS=$OIFS
            ;;
        "-nomenu" | "-no-menu" )
            NOMENU=:
            ;;
        "-out" )
            shift
            OUT_PREFIX="$1"
            OUT_PREFIX=${OUT_PREFIX%/}
            ;;
        "-no-ask" | "-noask" )
            NOASK=:
            ;;
        "-no-warn" | "-nowarn" )
            WARN=false
            ;;
        "-debug" )
            DEBUG=:
            KEEP_FILES=:
            ;;
        "-grid" )
            GRID=1
            ;;
        "-keep-files" )
            KEEP_FILES=:
            ;;
        "-dvd" )
            usage_error "Option removed, as todisc only does DVD's now"
            ;;
        "-svcd" )
            usage_error \
            "Todisc does only DVD's now.  Use the tovid, makemenu, makexml
            and makevcd scripts instead (simple menus)."
            ;;
        "-ntsc" )
            TV_STANDARD="ntsc"
            ;;
        "-pal" )
            TV_STANDARD="pal"
            ;;
        "-aspect" )
            unset ASPECT ASPECT_ARG
            shift
            ASPECT_ARG=$1
            if [[ ${#ASPECT_ARG[@]} -gt 0 ]]; then
            ASPECT_RATIO=$ASPECT_ARG
            [[ $ASPECT_RATIO = "16:9" ]] && AR=177 || AR=133
            V_ASPECT="aspect=\"$ASPECT_RATIO\""
            fi
            ;;
        "-widescreen" )
            shift
            get_listargs "$@"
            wsarg=${ARGS_ARRAY[0]}
            [[ -n $wsarg ]] &&  WIDESCREEN=$wsarg || WIDESCREEN="nopanscan"
            WIDE_SCREEN=:
            ;;
        "-showcase-safe-area" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            shift
            SAFE_AREA="$1"
            let SAFE_OFFSET="86-SAFE_AREA"
            USER_SAFE_AREA=:
            ;;
        "-align" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            shift
            BUTTON_GRAVITY=$1
            [[ $BUTTON_GRAVITY = "centre" ]] && BUTTON_GRAVITY="center"
            USER_GRAVITY=:
            ;;
        # Menu control options
        "-menu-length" )
            shift
            unset MENU_LEN
            get_listargs "$@"
            MENU_LEN=${ARGS_ARRAY[@]}
            MENU_LEN=( ${MENU_LEN//,/ } )
            USER_MENU_LEN=:
            ;;
        "-submenu-length" )
            shift
            get_listargs "$@"
            SUBMENU_LEN=${ARGS_ARRAY[@]}
            SUBMENU_LEN=( ${SUBMENU_LEN//,/ } )
            USER_SUBMENU_LEN=:
            ;;
        "-static" )
            STATIC=:
            ;;
        "-menu-fade" )
            shift
            get_listargs "$@"
            if [[ -n ${ARGS_ARRAY[0]} ]]; then
                if [[ ${ARGS_ARRAY[0]} = *:* ]]; then
                    transition_time=$(unformat_time ${ARGS_ARRAY[0]})
                else
                    transition_time=${ARGS_ARRAY[0]}
                fi
                if test_is_number $transition_time ; then
                    TRANSITION_TO_MENU_LEN=$transition_time
                else
                    usage_error "the argument for --menu-fade must be in
                    in seconds or HH:MM:SS format"
                fi
            else
                # use the default menu-fade
                TRANSITION_TO_MENU_LEN=1
            fi
            MENU_FADE=:
            AUDIO_FADE=:
            ;;
        "-transition-to-menu" )
            TRANSITION_TO_MENU=:
            MENU_FADE=:
            AUDIO_FADE=:
            ;;
        "-tile-3x1" | "-tile3x1" )
            THREExONE=:
            tile_arg="$1"
            ;;
        "-tile-4x1" | "-tile4x1" )
            FOURxONE=:
            tile_arg="$1"
            ;;
        "-thumb-columns") # same as -tile-4x1 and -tile-3x1
            tile_arg="$1"
            shift
            THUMB_COLUMNS=$1
            if [[ $THUMB_COLUMNS == 4 ]]; then
                FOURxONE=:
            elif [[ $THUMB_COLUMNS == 3 ]]; then
                THREExONE=:
            else
                usage_error "-thumb-columns uses only '3' or '4' as an argument"
            fi
            ;;
        "-loop" )
            unset pause_time
            shift
            #get_listargs "$@"
                unset x ARGS_ARRAY
            # if begins with '-' only -1 is a valid option, else stop
            while test $# -gt 0 && [[ ${1:0:2} != -[a-zA-Z2-9] ]]; do
                ARGS_ARRAY[x++]="$1"
                shift
            done
            # Do not skip past the next argument
            if test $# -gt 0 && test x"${1:0:1}" = x"-";then
                DO_SHIFT=false
            fi

            pause_time=${ARGS_ARRAY[0]}
            if [[ -n $pause_time ]]; then
                PAUSE_TIME=$pause_time
                ((PAUSE_TIME==-1)) && PAUSE_TIME='inf' # gui uses -1 for 'inf'
            else
                usage_error "-loop requires a numeric argument"
            fi
            USER_LOOP=:
            ;;
        "-video-pause" | "-slide-pause" )
            shift
            svcd_pause=$1
            get_listargs "$@"
            [[ -n "${ARGS_ARRAY[@]}" ]] && VPAUSE=( "${ARGS_ARRAY[@]}" )
            ;;
        "-group-video-pause" )
            shift
            get_listargs "$@"
            GRP_VPAUSE=( "${ARGS_ARRAY[@]}" )
            ;;
        "-slide-menu-mix" ) # removed
            shift
            usage_error "-slide-menu-mix has been changed - see manpage"
            ;;
        "-slideshow" ) # removed
            shift
            usage_error "Use -slides now instead of -slideshow"
            ;;
        "-slide-fade" ) # removed
            shift
            usage_error "Use -slide-transition fade|crossfade \
            now instead of -slide-fade"
            ;;
        "-menu-slide-total" )
            shift
            get_listargs "$@"
            MIX_RANGE=${ARGS_ARRAY[@]}
            MIX_RANGE=( ${MIX_RANGE//,/ } )
            ;;
        "-submenu-slide-total" )
            shift
            get_listargs "$@"
            SM_MIX_RANGE=${ARGS_ARRAY[@]}
            SM_MIX_RANGE=( ${SM_MIX_RANGE//,/ } )
            ;;
        "-slide-transition" )
            shift
            EFFECT=$1
            if ! egrep -q -w 'fade|crossfade'  <<< "$EFFECT"; then
                usage_error "The -slide-transition argument must be 'fade' \
                or 'crossfade' (default if option unused: 'crossfade')"
            fi
            SLIDE_FADE=:
            ;;
        "-background-slideshow" | "-bg-slideshow" )
            CAROUSEL_IS_BG=:
            SHOWCASE=:
            IMG_FMT="png"
            BG_SEEK=0
            ;;
        "-showcase-slideshow" )
            CAROUSEL_IS_SHOWCASE=:
            SHOWCASE=:
            IMG_FMT="png"
            SHOWCASE_SEEK_VAL=0
            ;;
        "-use-dvd-slideshow" )
            shift
            get_listargs "$@"
            if [[ -n ${ARGS_ARRAY[@]} ]]; then
                SLIDESHOW_CONF=$(readlink -f "${ARGS_ARRAY[0]}")
            fi
            USE_DVD_SLIDESHOW=:
            ;;
        "-jobs" )
            shift
            ! test_is_number $1 && \
            usage_error "-jobs requires a numerical argument (integer)"
            JOBS=$1
            max_procs=$JOBS
            ;;
        "-nr" )
            shift
            get_listargs "$@"
            if [[ ${ARGS_ARRAY[0]} ]]; then
                test_is_number ${ARGS_ARRAY[0]} && NR_AMT=${ARGS_ARRAY[0]}
            else
                usage_error "The argument to -nr must be an integer"
            fi
            NR="-nr"
            ;;
        "-slide-blur" )
            shift
            get_listargs "$@"
            if ((${#ARGS_ARRAY[@]} <= 1)); then
                if [[ -n ${ARGS_ARRAY[0]} ]]; then
                    SLIDE_BLUR_OPT=${ARGS_ARRAY[0]}
                else
                    SLIDE_BLUR_OPT=0x0.2
                fi
            else
                for f in ${!ARGS_ARRAY[@]}; do
                    SLIDE_BLUR_OPT[f]=${ARGS_ARRAY[f]}
                done
            fi
            ;;
        "-slides-to-blur" )
            shift
            get_listargs "$@"
            for f in ${!ARGS_ARRAY[@]}; do
                BLURFILES[f]=${ARGS_ARRAY[f]##*/}
            done
            ;;
        "-slides-to-bin" )
            shift
            get_listargs "$@"
            for f in ${!ARGS_ARRAY[@]}; do
                FILES2BIN[f]=${ARGS_ARRAY[f]##*/}
            done
            ;;
        "-slide-border" )
            shift
            get_listargs "$@"
            if [[ -n ${ARGS_ARRAY[0]} ]]; then
                if test_is_number ${ARGS_ARRAY[0]}; then
                    SBORDER_ARG=${ARGS_ARRAY[0]%%.*}
                else
                    usage_error \
                    "-slide-border takes a single integer as an argument"
                fi
            else # no argument given - set default at 100
                SBORDER_ARG=100
            fi
            ;;
        "-slide-frame" )
            shift
            get_listargs "$@"
            if [[ -n ${ARGS_ARRAY[0]} ]]; then
                if test_is_number ${ARGS_ARRAY[0]}; then
                    SFRAME_ARG=${ARGS_ARRAY[0]%%.*}
                else
                    usage_error \
                    "-slide-border takes a single integer as an argument"
                fi
            else # use default value
                SFRAME_ARG=12
            fi
            SLIDE_FRAME="-frame"
            ;;
        "-slide-frame-color" | "-slide-frame-colour" )
            opt=$1
            shift
            [[ -n $1 ]] && SFRAME_CLR="$1" ||
             usage_error "$opt takes an argument - the ${opt/*-} for the frame"
            ;;
        "-chain-videos" )
            shift
            get_listargs "$@"
            chains_in=${ARGS_ARRAY[@]}
            post_play=${chains_in//,/ }
            CHAIN_VIDEOS=:
            ;;
        "-playall" )
            PLAYALL=:
            ;;
        "-background" )
            shift
            BACKGROUND=$(readlink -f "$1")
            USERS_BACKGROUND=:
            ! [[ -e "$BACKGROUND" ]] && \
            usage_error "background \"$BACKGROUND\" does not exist"
            ;;
        "-submenu-background" )
            shift
            get_listargs "$@"
            for f in  ${!ARGS_ARRAY[@]}; do
                SM_BACKGROUND[f]=$(readlink -f "${ARGS_ARRAY[f]}")
                ! [[ -e ${SM_BACKGROUND[f]} ]] && usage_error \
                "submenu background \"$SM_BACKGROUND\" does not exist"
            done
            ;;
        "-intro" )
            shift
            DO_INTRO=:
            INTRO_CLIP=$(readlink -f "$1")
            ! [[ -e "$INTRO_CLIP" ]] && \
            usage_error "intro clip \"$INTRO_CLIP\" does not exist"
            ;;
        "-showcase" )
            shift
            get_listargs "$@"
            unset f
            for f in  ${!ARGS_ARRAY[@]}; do
                SHOWCASE_FILE[f]=$(readlink -f "${ARGS_ARRAY[f]}")
            done
            SHOWCASE=:
            IMG_FMT="png"
            ;;
        "-textmenu" | "-text-menu" )
            shift
            get_listargs "$@"
            arg=${ARGS_ARRAY[0]}
            [[ -n $arg ]] && SPLIT=$arg && USER_SPLIT=:
            TEXTMENU=:
            ;;
        "-text-start" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            shift
            TEXT_YSTART=$1
            ;;
        "-showcase-titles-align" )
            shift
            SC_TITLE_ALIGN="$1"
            [[ SC_TITLE_ALIGN = "centre" ]] && SC_TITLE_ALIGN="center"
            ;;
        "-title-gap" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            shift
            SPACER=$1
            ;;
        "-rotate" )
            shift
            ROTATE_DEGREES="$1"
            if test_is_number $ROTATE_DEGREES; then
                ROTATE="-rotate $ROTATE_DEGREES"
            else
                usage_error "Argument to -rotate must be a number"
            fi
            IMG_FMT="png"
            ;;
        "-wave" )
            shift
            get_listargs "$@"
            wave=${ARGS_ARRAY[0]}
            if [[ -n $wave ]]; then
                if [[ $wave = "default" ]]; then
                    WAVE="-wave -20x556"
                else
                    WAVE="-wave $wave"
                fi
            else
                # a hack to address a current lack in metagui for todiscgui
                WAVE="-wave -20x556"
            fi
            ;;
        "-showcase-framestyle" )
            shift
            SC_FRAMESTYLE="$1"
            ;;
        "-thumb-shape" )
            shift
            THUMB_SHAPE="$1"
            FEATHER=:
            IMG_FMT="png"
            ;;
        "-showcase-shape" )
            shift
            SHOWCASE_SHAPE="$1"
            ;;
        "-button-style" )
            shift
            BUTTON_STYLE="$1"
            USER_BSTYLE=:
            ;;
        "-3d-thumbs" | "-3dthumbs" )
            THUMBS_3D=:
            RAISE="-raise 8x8"
            ;;
        "-3d-showcase" | "-3dshowcase" )
            SHOWCASE_3D=:
            SC_RAISE="-raise 8x8"
            ;;
        "-thumb-frame-colour" | "-thumb-frame-color" )
            shift
            THUMB_FRAME_CLR="$1"
            ;;
        "-thumb-frame-size" )
            shift
            tfsize="$1"
            if test_is_number "$tfsize"; then
                THUMB_FRAME_SIZE="${tfsize}x${tfsize}"
                USER_THUMB_FRAME_SIZE=1
            else
                usage_error "-thumb-frame-size requires an integer as argument"
            fi
            ;;
        "-showcase-frame-colour" | "-showcase-frame-color" )
            shift
            SHOWCASE_FRAME_CLR="$1"
            ;;
        "-showcase-frame-size" )
            shift
            sfsize="$1"
            if test_is_number "$sfsize"; then
                SHOWCASE_FRAME_SIZE="${sfsize}x${sfsize}"
                USER_SHOWCASE_FRAME_SIZE=1
            else
                usage_error "-showcase-frame-size requires an integer as argument"
            fi
            ;;
        "-thumb-blur" | "-blur" )
            shift
            if ! test_is_number "$BLUR"; then
                usage_error "-blur requires an integer as argument"
            fi
            THUMB_BLUR="$1"
            (( ${THUMB_BLUR%.*} >= 2 )) && THUMB_BLUR=2
            USER_BLUR=1
            ;;
        "-showcase-blur" )
            shift
            if ! test_is_number "$SC_BLUR"; then
                usage_error "-showcase-blur requires an integer as argument"
            fi
            SC_BLUR="$1"
            (( ${SC_BLUR%.*} >= 2 )) && SC_BLUR=2
            SC_USER_BLUR=1
            ;;
        "-title-colour" | "-title-color" )
            shift
            TITLE_CLR="$1"
            ;;
        "-submenu-font" )
            shift
            SM_TITLE_FONT="$1"
            ;;
        "-submenu-fontsize" )
            shift
            SUBMENU_FONTSIZE="$1"
            ;;
        "-submenu-title-colour" | "-submenu-title-color" )
            shift
            SM_TITLE_CLR="$1"
            ;;
        "-title-stroke" )
            shift
            TITLE_STROKE="$1"
            ;;
        "-titles-stroke" )
            shift
            TITLES_STROKE="$1"
            ;;
        "-submenu-stroke" )
            shift
            SUBMENU_STROKE="$1"
            ;;
        "-titles-opacity" )
            shift
            test_is_number $1 && TITLES_OPACITY="$1"
            ;;
        "-title-opacity" )
            shift
            test_is_number $1 && TITLE_OPACITY="$1"
            ;;
        "-submenu-title-opacity" )
            shift
            test_is_number $1 && SM_TITLE_OPACITY="$1"
            ;;
        "-chapter-title-opacity" )
            shift
            test_is_number $1 && CHAPTER_TITLES_OPACITY="$1"
            ;;
        "-chapter-stroke" )
            shift
            CHAPTER_STROKE="$1"
            ;;
        "-chapter-color" | "-chapter-colour" )
            shift
            CHAPTER_CLR="$1"
            ;;
        "-titles-colour" | "-titles-color" )
            shift
            TITLES_CLR="$1"
            ;;
        "-highlight-colour" | "-highlight-color" )
            shift
            HLIGHT_CLR="$1"
            ;;
        "-select-colour" | "-select-color" )
            shift
            SELECT_CLR="$1"
            ;;
        -thumb-text-col* | "-thumb-font" | "-thumb-fontsize" ) # removed
            usage_error \
            "The $1 option has been renamed.  Now use: -titles-${1##*-}"
            ;;
        *-stroke-col* ) # removed
            usage_error "The $1 option has been renamed.  Now use: ${1%-*}"
            ;;
        "-text-mist" )
            MIST=:
            ;;
        "-text-mist-opacity" )
            shift
            MIST_OPACITY="$1"
            ;;
        "-text-mist-colour" |"-text-mist-color" )
            shift
            MIST_COLOUR="$1"
            ;;
        "-thumb-mist-colour" |"-thumb-mist-color" )
            usage_error "$1 has been removed.  Use ${1%-*} [COLOR]"
            ;;
        "-thumb-mist" )
            unset thumb_bg_colour
            shift
            get_listargs "$@"
            thumb_bg_colour=${ARGS_ARRAY[0]}
            if [[ -n $thumb_bg_colour ]]; then
                THUMB_BG_CLR=$thumb_bg_colour
            else
                THUMB_BG_CLR="#FFFFFF" # default colour without args
            fi
            USE_FEATHER_MASK=:
            ;;
        "-opacity" )
            shift
            TRANSPARENT=:
            OPACITY="$1"
            ;;
        "-chapters" )
            unset CHAPTERS
            shift
            get_listargs "$@"
            CHAPTERS=${ARGS_ARRAY[@]}
            # user can pass HH:MM:SS chapters, else, remove possible comma sep
            ! [[ "$CHAPTERS" = *:* ]] && CHAPTERS=( ${CHAPTERS//,/ } )
            # a way to tell later if user passed HH:MM:SS chapters
            if [[ "$CHAPTERS" = *:* ]]; then
                [[ "$CHAPTERS" = *+* ]] && grouped_user_chapters=( $CHAPTERS )
                # make array, remove everything after and including 1st '+',
                CHAPTERS=( $CHAPTERS )
                #CHAPTERS=( ${CHAPTERS[@]%%+*} ) # in case of grouped chapters
                USER_CHAPTERS=: # user passed HH:MM:SS chapters
            fi
            ;;
        "-subtitle-lang" )
            shift
            SUBTITLES=:
            get_listargs "$@"
            SUBS=${ARGS_ARRAY[@]}
            SUBS_ARRAY=( ${SUBS//,/ } )
            ;;
        "-audio-channel" )
            shift
            get_listargs "$@"
            AUDIO_CHANNEL=${ARGS_ARRAY[@]}
            AUDIO_CHANNEL=( ${AUDIO_CHANNEL//,/ } )
            ;;
        "-audio-lang" )
            o=$1
            shift
            get_listargs "$@"
            LANGS=${ARGS_ARRAY[@]}
            LANGS=( ${LANGS//,/ } )
            for i in ${LANGS[@]}; do
                test_is_number "$i" && \
                usage_error "$o is for language codes now:
                perhaps you wanted '-audio-channel' ?"
            done
            ;;
        "-bgaudio" | "-bg-audio" )
            shift
            if [[ $1 = "none" ]]; then
                BG_AUDIO="none" # for switched menus
            else
                BG_AUDIO=$(readlink -f "$1")
                if [[ ! -e "$BG_AUDIO" ]]; then
                    usage_error "background audio \"$BG_AUDIO\" does not exist"
                fi
            fi
            ;;
        "-menu-audio-fade" )
            shift
            FADE="$1"
            AUDIO_FADE=:
            ;;
        "-submenu-audio" )
            shift
            get_listargs "$@"
            for i in ${!ARGS_ARRAY[@]}; do
                if [[ ${ARGS_ARRAY[i]} = "none" ]]; then
                    SM_AUDIO=( "${SM_AUDIO[@]}" "${ARGS_ARRAY[i]}" )
                else
                    if [[ ! -e "${ARGS_ARRAY[i]}" ]]; then
                        usage_error "audio file \"${ARGS_ARRAY[i]}\" not found"
                    else
                        SM_AUDIO=( "${SM_AUDIO[@]}" \
                        "$(readlink -f "${ARGS_ARRAY[i]}")" )
                    fi
                fi
            done
            SUBMENU_AUDIO=:
            ;;
        "-submenu-audio-fade" )
            shift
            SM_FADE="$1"
            ;;
        "-submenu-audio-length" ) # removed
            usage_error "The $1 option has been removed. Use -submenu-length to
            set the length of submenu audio for a static submenu. (yes now
            submenu lengths can be set)"
            ;;
        "-submenus" )
            SUB_MENU=:
            ;;
        "-ani-submenus" )
            ANI_SUB_MENU=:
            SUB_MENU=:
            ;;
        "-menu-title" )
            shift
            MENU_TITLE="$1"
            ;;
        "-menu-font" )
            shift
            MENU_FONT=$(get_font "$1")
            ;;
        "-menu-fontsize" )
            shift
            MENU_FONTSIZE="$1"
            ;;
        "-titles-font" )
            shift
            TITLES_FONT=$(get_font "$1")
            ;;
        "-titles-fontsize" )
            shift
            TITLES_FONTSIZE="$1"
            ;;
        "-chapter-font" )
            shift
            CHAPT_FONT=$(get_font "$1")
            ;;
        "-chapter-fontsize" )
            shift
            get_listargs "$@"
            CHAPT_FONTSIZE=( ${ARGS_ARRAY[@]} )
            ;;
        "-seek" )
            shift
            unset SEEK_VAL
            get_listargs "$@"
            SEEK_VAL=${ARGS_ARRAY[@]}
            SEEK_VAL=( ${SEEK_VAL//,/ } )
            USER_SEEK_VAL=:
            ;;
        "-showcase-seek" )
            shift
            SHOWCASE_SEEK_VAL="$1"
            ;;
        "-bg-video-seek" | "-bgvideo-seek" )
            shift
            BG_SEEK="$1"
            ;;
        "-bg-audio-seek" | "-bgaudio-seek" )
            shift
            BG_AUDIO_SEEK="$1"
            USER_BG_AUDIO_SEEK=:
            ;;
        "-showcase-geo" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            shift
            USER_SC_GEO=:
            SHOWCASE_GEO=$1
            ;;
        "-submenu-audio-seek" ) # not implemented yet
            shift
            get_listargs "$@"
            SM_AUDIO_SEEK=( ${ARGS_ARRAY[@]} )
            USER_SM_AUDIO_SEEK=:
            ;;
        "-menu-title-geo" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            USER_TITLE_GEO=:
            shift
            TITLE_GRAVITY=$1
            TITLE_GRAVITY=${TITLE_GRAVITY/re/er}
            ;;
        "-menu-title-offset" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            USER_TITLE_GEO=:
            shift
            xpr='([-+][0-9]+)([-+][0-9]+)'
            [[ $1 =~ $xpr ]]
            [[ -n ${BASH_REMATCH[1]} ]] && title_xoffset=${BASH_REMATCH[1]}
            [[ -n ${BASH_REMATCH[2]} ]] && title_yoffset=${BASH_REMATCH[2]}
            ;;
        "-outlinewidth" )
            ADV_OPT=( "${ADV_OPT[@]}" "$1" )
            shift
            OUTLINEWIDTH="\"$1\""
            ;;
        "-rotate-thumbs" )
            shift
            parse_rotateargs "$@"
            ROTATE_ARRAY=( "${ARGS_ARRAY[@]}" )
            IMG_FMT="png"
            ROTATE_THUMBS=:
            ;;
        "-tovidopts" | "-tovid-opts" )
            usage_error "The -tovidopts option no longer exists.  Now just use
            the tovid options directly on the command line."
            ;;
        "-titleset-mode" ) # internal use only
            AUTHOR=false
            TITLESET_MODE=:
            ;;
        "-switched-mode" ) # internal use only
            SWITCHED_MODE=:
            TEXTMENU=:
            SC_TITLE_ALIGN="west"
            SHOWCASE=:
            ;;
        "-vmgm_only" ) # internal use only
            VMGM_ONLY=:
            ;;
        "-basedir" ) # internal use only
            shift
            BASEDIR="$1"
            ;;
        "-tset_num" ) # internal use only
            shift
            TSET_NUMS="$1"
            TSET_NUM=${TSET_NUMS/*-}
            TSET_TOT=${TSET_NUMS/-*}
            ;;
        "-vmgm_playall" ) # internal use only
            VMGM_PLAYALL=:
            ;;
        "-todisc_pids" ) # internal use only
            shift
            TODISC_PIDS="$TODISC_PIDS $1"
            ;;
        "-menu_num" ) # internal use only
            shift
            MENU_NUM="$1"
            ;;
        "-carousel_num" ) # internal use only
            shift
            CAROUSEL_NUM="$1"
            ;;
        "-title_count" ) # internal use only
            shift
            ALLTITLES=( $1 )
            ;;
        "-quick-nav" )
            QUICK_NAV=:
            ;;
        "-switched-menus" | "-switched-menu" )
            SWITCHED_MENUS=:
            TEXTMENU=:
            SHOWCASE=:
            SC_TITLE_ALIGN="west"
            ;;
        "-skip-vmgm" )
            SKIP_VMGM_MENU=:
            ;;
        "-no-vmgm-menu" | "-no-vmgm" )
            VMGM_MENU=false
            ;;
        "-no-top-menu" )
            usage_error "Option removed - no SVCD output available now"
            ;;
        "-videos-are-chapters" )
            VIDEOS_ARE_CHAPTERS=:
            ;;
        "-is_titleset" ) #FIXME - this is useless
            TSET_MODE=:
            ;;
        "-carousel_menu_mode" ) # internal use only
            MK_CAROUSEL_MODE=:
            ;;
        "-no-confirm-backup" )
            CONFIRM_BACKUP=false
            ;;
        "-burn" )
            BURN=:
            ;;
        "-device" )
            shift
            BURN_DEVICE="$1"
            ;;
        "-speed" )
            shift
            SPEED="$1"
            BURN_SPEED="-speed $SPEED"
            ;;
        "-quick-menu" )
            QUICK_MENU=:
            ;;
        "-bg-colour" | "-bg-color" )
            shift
            BG_CLR="$1"
            ;;
        "-submenu-bg-colour" | "-submenu-bg-color" )
            shift
            SUBMENU_BG_CLR="$1"
            ;;
        "-config" | "-ntscfilm" | "-dvd-vcd" | "-half-dvd" | "-kvcd" | \
        "-kvcdx3" | "-kvcdx3a" | "-kdvd" | "-bdvd" | "-704" | "-normalize" | \
        "-amplitude" | "-overwrite" | "-panavision" | "-force" | "-fps" | \
        "-vbitrate" | "-quality" | "-safe" | "-crop" | "-filters" | \
        "-abitrate" | "-priority" | "-deinterlace" | "-progressive" | \
        "-interlaced" | "-interlaced_bf" | "-type" | "-fit" | "-discsize" | \
        "-parallel" | "-mkvsub" | "-autosubs" | "-subtitles" | "-update" | \
        "-mplayeropts" | "-audiotrack" | "-downmix" | "-ffmpeg" | "-nofifo" | \
        "-from-gui" | "-noask" | "-slice" | "-async" | "-quiet" | \
        "-fake" | "-keepfiles" )
            # remove this warning for tovid 0.33 TODO
            if [[ $1 = "-subtitles" ]]; then
                if (( ${#2} == 2 )); then
                    usage_error "todisc's '-subtitles' option has been changed
                    to '-subtitle-lang', so it doesn't conflict with a tovid
                    option by the same name"
                elif [[ ! -e $2 ]]; then
                    usage_error " subtitle file $2 does not exist"
                else
                    TOVID_OPTS+=( "$1" "$(readlink -f "$2")" )
                fi
            elif [[ $1 == "-config" ]]; then
                if [[ ! -e $2 ]]; then
                    usage_error "config file $2 does not exist"
                else
                    TOVID_OPTS+=( "$1" "$(readlink -f "$2")" )
                fi
            else
                TOVID_OPTS+=( "$1" )
                shift
                get_listargs "$@"
                TOVID_OPTS+=( "${ARGS_ARRAY[@]}" )
            fi
            ;;
        -car* )
            usage_error "$1: No such option.  Please see 'man tovid' ?"
            ;;
    esac
    $DO_SHIFT && shift
done

##############################################################################
#                      Sanity checks and preliminaries                       #
##############################################################################
# get script pid so we can kill the parent if doing recursive todisc's
TODISC_PIDS="$TODISC_PIDS $$"

# make sure dvd-slideshow is installed if user passed -use-dvd-slideshow
$USE_DVD_SLIDESHOW && assert_dep dvd-slideshow \
"The program dvd-slideshow was not found - you can get it from
dvd-slideshow.sourceforge.net.  Note: if you do not use
-use-dvd-slideshow, todisc will create the slideshow video for you. "
assert_dep pgrep "You need the pgrep program to use todisc"
if $USE_DVD_SLIDESHOW; then
    if $STATIC && $ANI_SUBMENUS ||
     ((sshows>1 || inc_files>=1)); then
        usage_error "Sorry you can only use the dvd-slideshow program with
        single slideshows"
    fi
fi
# make sure user has backed up personal image files
((sshows>=1)) && $CONFIRM_BACKUP && confirm_backup
# link WORK_DIR to /tmp for easy solution to spaces, illegal chars bugs
! $GROUPING && mk_workdir
# set some other vars now that depended on *WORK_DIR being set
SPUMUX_XML="$WORK_DIR/spumux.xml"
DVDAUTHOR_XML="$WORK_DIR/dvdauthor.xml"
PREVIEW_IMG="$WORK_DIR/preview.jpg"

# check for multiple cpus if -jobs not passed already
#TODO always wait for either 1 or 2 processes - no need for if block later
if [[ -z $JOBS ]]; then
    proc_cnt=$(grep ^processor /proc/cpuinfo |awk 'END{print $NF+1}')
    max_procs=$proc_cnt
fi

if $BURN; then
    if [[ ! -b $(readlink -f $BURN_DEVICE) ]]; then
        usage_error \
        "$BURN_DEVICE is not a valid block device file or link to a block device.
        Are you sure your burner is \"${BURN_DEVICE}\"? Specify your burner with
        -device /path/to/burner."
    fi
fi

# Make sure equal, nonzero number of titles and files were provided

if ! $VMGM_ONLY && ! $DO_TITLESETS; then
    ((num_slideshows>0)) && ss_err="  A slideshow counts as one file.
     Please give one title for each slideshow. "
    if [[ ${#FILES[@]} -eq 0 ]]; then
        usage_error "Please provide at least one file."
    elif [[ -n ${TITLES[@]} ]] && [[ ${#FILES[@]} -ne ${#TITLES[@]} ]]; then
        if $SINGLE_SLIDESHOW; then
            ERR="Please do not pass '-titles' if doing a single slideshow"
        else
            ERR="Please give the same number of titles as files.
        You gave ${#FILES[@]} files and ${#TITLES[@]} titles.$ss_err"
        fi
        usage_error "$ERR"
    fi
fi
$SWITCHED && MN=2 || MN=1

if [[ ${#TITLES[@]} -eq 0 ]]; then
    if [[ $MENU_NUM = $MN ]] && ! $NOMENU \
     && ! $SINGLE_SLIDESHOW && ! $DO_TITLESETS && $MONTAGE_MENU; then
        yecho
        yecho "You did not provide any titles with -titles"
        yecho "Using the basename of each file provided (minus the extension)."
        yecho
        ((sshows < 1)) && $WARN && sleep 5
    fi
    for i in ${!FILES[@]}; do
        TITLE=${FILES[i]##*/}
        TITLES[i]=" ${TITLE%%.*} "
    done
fi
if ! $TITLESET_MODE && ! $DO_TITLESETS && $QUICK_NAV && ! $VMGM_ONLY; then
    QUICK_NAV=false
    yecho
    yecho "No -quick-nav unless doing titlesets ... disabling this option"
    $WARN && sleep 5
    yecho
fi
if $DO_TITLESETS && ! $VMGM_MENU && ! $QUICK_NAV; then
    usage_error \
    "You can not use -no-vmgm if doing titlesets unless using -quick-nav"
fi
# some things the vmgm menu does not support
if $VMGM_ONLY; then
    SUB_MENU=false
    ANI_SUB_MENU=false
#    QUICK_MENU=false
    SM_TITLES=""
fi
# flesh out options needed for -quick-menu,-textmenu.  Check slideshow opts
if $QUICK_MENU; then
    if $MENU_FADE; then
        usage_error "-quick-menu is incompatible with -menu-fade"
    fi
    SC_TITLE_ALIGN="west"
    SHOWCASE=:
fi
if $TEXTMENU; then
    SHOWCASE=:
    IMG_FMT="png"
    SC_TITLE_ALIGN="west"
fi
# incompatible slideshow options with -switched-menus
if { $CAROUSEL_IS_BG || $CAROUSEL_IS_SHOWCASE ; } && $SWITCHED_MENUS; then
    $CAROUSEL_IS_BG && OPT="-background-slideshow" || OPT="-showcase-slideshow"
    yecho
    yecho "$OPT uses slides from ALL slideshows, so its use with
     -switched-menus makes no sense.  Removing this option for you."
    yecho
    CAROUSEL_IS_SHOWCASE=false; CAROUSEL_IS_BG=false
    $WARN && sleep 10
fi
# slideshows are animated by default like rest of todisc
if ((sshows>=1)); then
    if $STATIC && \
     { ! $CAROUSEL_IS_SHOWCASE && ! $CAROUSEL_IS_BG ; }; then
        :
    else
        DO_CAROUSEL=:
        is_carousel=:
        SLIDE_FADE=:
    fi
fi
#if $DO_CAROUSEL && $SHOWCASE && ! { $SWITCHED_MODE || $SWITCHED_MENUS ; } && \
# ! $CAROUSEL_IS_BG && ! $CAROUSEL_IS_SHOWCASE && ((sshows<=1)); then
#    yecho
#    usage_error "You are using an animated slideshow but not making a background or
#    showcase slideshow, so -textmenu or -showcase makes no sense."
#fi

if [[ -n "$SM_TITLES" ]]; then
    if test ${#SM_TITLES[@]} -ne ${#TITLES[@]}; then
    usage_error "Please give the same number of submenu titles as titles.
    You gave ${#SM_TITLES[@]} submenu titles and ${#TITLES[@]} titles"
    fi
fi
# titlesets use BASEDIR which is the WORK_DIR of the calling todisc
# BASEDIR is supplied by the calling todisc with -basedir
: ${BASEDIR:="$WORK_DIR"}

# Make sure -out was provided and it is valid
if test -n "$OUT_PREFIX"; then
    OUT_DIR=$(readlink -f "$OUT_PREFIX")
    if [[ ! -d ${OUT_DIR%/*} ]]; then
        OUT_PATH=$(readlink -m "$OUT_PREFIX")
        usage_error "The -out path ${OUT_PATH%/*}/ does not exist"
    fi
    if egrep -q '<|>|&' <<< "$OUT_DIR"; then
        usage_error "Sorry, dvdauthor will not let you use a -out name \
        with '>', '<' or '&' in it.  Please choose another directory or \
        name for -out  You used: $OUT_DIR"
    elif test $(wc -l <<< "$(echo -e "$OUT_DIR")") -gt 1; then
        usage_error "Dvdauthor does not allow multiline directory names.  
        Please change the directory you gave as an -out argument."
    fi
else
    usage_error "Please provide an output name with -out"
fi
# for dvdauthor.xml, if -intro was used
$DO_INTRO && INTRO="<vob file=\"$INTRO_CLIP\"/>"

# switched menus need more than one video file
if $SWITCHED_MENUS && [[ ${#FILES[@]} -eq 1 ]]; then
    usage_error "You can not use switched menus with only one file"
fi

# don't make submenus on each recursive call in switched mode
if $SWITCHED_MODE; then
    ANI_SUB_MENU=false && SUB_MENU=false
fi
# disable submenus for some options
if $SUB_MENU && $SINGLE_SLIDESHOW; then
    usage_error "Sorry, no submenu for a single slideshow"
fi

if $VMGM_ONLY; then SWITCHED_MODE=false && SWITCHED_MENUS=false; fi
# -no-vmgm requires -skip-vmgm:  pass -no-vmgm-menu to subshells via NO_VMGM
if ! $VMGM_MENU; then
    SKIP_VMGM_MENU=:
    NO_VMGM="-no-vmgm-menu"
fi
if [ ${#MENU_LEN[@]} -eq 1 ]; then
    for ((i=0; i<${#FILES[@]}; i++)); do
        MENU_LEN[i]=${MENU_LEN[0]}
    done
fi
# initialize MENU_AUDIOLEN now that options have been read
[[ -n $BG_AUDIO ]] && MENU_AUDIOLEN=${MENU_LEN[MENU_NUM-1]}

# ffmpeg noise reduction
if [[ -n $NR ]]; then
    [[ -z $NR_AMT ]] && NR_AMT=200
    NR="$NR $NR_AMT"
fi

# assign values for slides
# blurs
if [[ -n ${BLURFILES[@]} ]]; then
    for i in ${!BLURFILES[@]}; do
        if [[ -z ${SLIDE_BLUR_OPT[i]} ]]; then
            SLIDE_BLUR_OPT[i]=${SLIDE_BLUR_OPT[0]}
        fi
    done
fi
# frames
if [[ -n $SLIDE_FRAME ]]; then # we are framing slides
    SFRAME=${SFRAME_ARG}x${SFRAME_ARG}
    SLIDE_FRAME="$SLIDE_FRAME $SFRAME"
fi
# now that frame-sizes and frame colours have been read in, set some vars

SHOWCASE_FRAME="-bordercolor  $SHOWCASE_FRAME_CLR -compose Copy"
SHOWCASE_FRAME="$SHOWCASE_FRAME -border $SHOWCASE_FRAME_SIZE"
# no frame with -3d-showcase
$SHOWCASE_3D && unset SHOWCASE_FRAME
# allow -showcase-frame-size (otherwise unused for 3D showcase) to set -raise
((USER_SHOWCASE_FRAME_SIZE)) && SC_RAISE="-raise $SHOWCASE_FRAME_SIZE"
THUMB_FRAME="-shave $THUMB_FRAME_SIZE +repage -border $THUMB_FRAME_SIZE"
# no frame with 3D thumbs which use '-raise'
$THUMBS_3D && unset THUMB_FRAME
# allow -thumb-frame-size (otherwise unused for 3D thumbs) to set -raise
((USER_THUMB_FRAME_SIZE)) && RAISE="-raise $THUMB_FRAME_SIZE"


# honour -noask for functions and called scripts that use them
$NOASK && NO_ASK="-noask"
# Warn if thumb labels have more than 16 characters
if ! $SHOWCASE; then
    for ((i=0; i<${#TITLES[@]}; i++)); do
        val=${#TITLES[i]}
        [ -z "$MAX_CHARS" ] || ((val > MAX_CHARS)) && MAX_CHARS=$val && key=$i
    done
    if [[ ${#TITLES[@]} -gt 6 \
    && $MAX_CHARS -gt 16 ]] && ! $SINGLE_SLIDESHOW; then
        yecho
        yecho "WARNING! Some titles are longer than 16 characters; \
        they may be chopped off."
        yecho
        #echo "\"${TITLES[key]}\" is too long; please use a shorter title."
        #exit 1
    fi
fi
# get argument for transcode's progress reporting based on version
_transcode_version=$(transcode -v 2>&1| awk '{gsub("v", ""); print $2}')
_baseline_version=1.1.0
if test_version $_transcode_version $_baseline_version; then
    transcode_arg=--progress_rate
else
    transcode_arg=--print_status
fi
# set some vars for switched menus so we know where we are
$SWITCHED_MODE && SWITCHED_MENUS=false
{ $SWITCHED_MODE || $SWITCHED_MENUS ; } && SWITCHED=:
# warn about change in -thumb-mist option
if $FEATHER && ! $USE_FEATHER_MASK; then
    yecho
    yecho "Note: feathered thumb shapes no longer have mist background
        by default.  Use -thumb-mist [COLOR] to get the old behavior"
    yecho
    $WARN && sleep 5
fi
#
# sanity checks for button style ( -button-style ) for menu buttons
#

# use a suitable button style
if ! $SINGLE_SLIDESHOW; then
    for ((i=0; i<${#FILES[@]}; i++)); do
        if test $(wc -l <<< "$(echo -e "${TITLES[i]}")") -gt 1; then
            MULTILINE_TITLE=:
            if $FEATHER && [ $THUMB_SHAPE != "normal" ]; then
                # multiline titles not suitable for text buttons
                BUTTON_STYLE="text-rect"
            elif $TEXTMENU; then
                [[ $BUTTON_STYLE != "line" ]] && BUTTON_STYLE="text-rect"
            else
                [[ $BUTTON_STYLE != "text-rect" ]] \
                && ! $USER_BSTYLE && BUTTON_STYLE="rect"
            fi
        fi
    done

    # disallow spaces in thumb titles for text button style
    if [ "$BUTTON_STYLE" = "text" ]; then
        for ((i=0; i<${#TITLES[@]}; i++)); do
            T=$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${TITLES[i]}")
            if grep "  " <<< "$T" >/dev/null; then
                echo "Sorry, a maximum of one consecutive space is allowed
                in titles for text buttons.  \"${TITLES[i]}\" has more than
                one consecutive space in it" |fold -bs
                exit 1
            fi
        done
        if $TITLESET_MODE && $VMGM_MENU && $PLAYALL && ! $SHOWCASE; then
            BUTTON_STYLE="rect"
            yecho
            yecho "Warning ************"
            yecho "You can not use text button style when using both \
            playall and titlesets"
            yecho "because of spumux and space limitations"
            yecho "Changing to 'rect' style of buttons"
            $WARN && sleep 15
        fi
    fi
fi
if { $TEXTMENU || $QUICK_MENU ; } && [[ $BUTTON_STYLE = "rect" ]]; then
    if $MULTILINE_TITLE; then
        BUTTON_STYLE="text-rect"
    else
        BUTTON_STYLE="line"
    fi
    if ((MENU_NUM==2)) || { ! $SWITCHED_MODE && ! $SWITCHED_MENUS ; }; then
        if $USER_BSTYLE; then
            yecho
            yecho "Using button style '$BUTTON_STYLE' instead of 'rect'
            for textmenu menu"
            yecho
            $WARN && sleep 10
        fi
    fi
fi
# allow multiline titles in submenu
if [[ -n "$SM_TITLES" ]]; then
    for i in ${!SM_TITLES[@]}; do
        if [[ $(echo -e "${SM_TITLES[i]}" |wc -l) -gt 1 ]]; then
            SM_TITLES[i]="$(echo -e  "${SM_TITLES[i]}")"
        fi
    done
fi
# check if user passed a usable thumb or showcase shape
if [[ -n $THUMB_SHAPE ]]; then
    if ! check_maskshape $THUMB_SHAPE; then
        usage_error "Please supply a usable thumb shape with
        -thumb-shape option. You gave \"$THUMB_SHAPE\""
    fi
            
fi
if [[ -n $SHOWCASE_SHAPE ]]; then
    if ! check_maskshape $SHOWCASE_SHAPE; then
        usage_error "Please supply a usable showcase shape with
        -showcase-shape option.  You gave \"$SHOWCASE_SHAPE\""
    fi
fi
if [[ -n ${ROTATE_ARRAY[@]} ]]; then
    if ! $SHOWCASE; then
         if [[ $BUTTON_STYLE = *rect* ]]; then
            BUTTON_STYLE="line"
            if $USER_BSTYLE; then
                yecho
                echo "'*rect' button styles with rotated thumbs don't play well"
                echo "with spumux buttons. Setting button style to "
                echo "'line'.  You may also use 'text' style"
                echo "Quit now if you wish to exit and examine your options"
                yecho
                $WARN && sleep 10
            fi
        fi
    fi
fi
if ! $SINGLE_SLIDESHOW; then
    for i in ${!FILES[@]}; do
        if [[ ! ${TITLES[i]} && $BUTTON_STYLE != "rect" ]]; then
            usage_error "You can not use \"$BUTTON_STYLE\" button style if
            you have no titles.  Use 'rect' style instead"
        fi
    done
fi
#
# end of button-style checks
#

# transparent border around text so rect spumux outline can fit
if [[ $BUTTON_STYLE = "text-rect" ]]; then
    TEXT_BORDER="-bordercolor Transparent -border 8x8"
fi

# If output directory already exists, print a message and exit
if test -e "$OUT_DIR"; then
    echo "Cleaning up created dirs"
    yecho
    echo "A file or directory named \"$OUT_DIR\" already exists."
    echo "Please use a different -out name, "
    echo "or (re)move the existing file or directory."
    rm -rf "$REAL_WORK_DIR"
    rm -f "$WORK_DIR"
    exit 1
fi
# Remove any existing log file unless recursing
if ! $SWITCHED_MODE && ! $TITLESET_MODE && \
! $MK_CAROUSEL_MODE && ! $VMGM_ONLY; then
    test -f "$LOG_FILE" && rm -fv "$LOG_FILE"
fi
# see if imagemagick supports -vignette for the oval shape
if [[ $THUMB_SHAPE == "vignette" || $SHOWCASE_SHAPE == "vignette" ]]; then
    if ! convert -help 2>&1 | egrep -q -- "-vignette"; then
        [[ $THUMB_SHAPE == "vignette" ]] && THUMB_SHAPE="oval"
        [[ $SHOWCASE_SHAPE == "vignette" ]] && SHOWCASE_SHAPE="oval"
        ! ((USER_BLUR)) && BLUR=3
        ! ((SC_USER_BLUR)) && SC_BLUR=3
        warning_message \
          "INFO: -vignette option not available in your imagemagick version.
          You should upgrade it.  Using 'oval' mask shape instead which is
          similar.  Setting the blur to 3 unless you used '-blur' (thumbs) or
          '-showcase-blur' (showcase file)"
        $WARN && sleep 5
    fi
fi
# see if advanced options were used and give warning if so
if [[ -n "${ADV_OPT[@]}" ]] && ! $SWITCHED_MODE; then
    yecho
    yecho "***** WARNING *****"
    yecho "You have used the following advanced options:"
    yecho "${ADV_OPT[@]}" | format_output
    yecho "With these options it is possible to create a menu where things \
    overlap or are offscreen, or that has other problems, so please check it \
    with the preview.  These are things that todisc tries to avoid normally, \
    so if you have problems, please leave them out."
    yecho
    $WARN && sleep 15
fi

# copy symlinks for -group hack
if $GROUPING && $TITLESET_MODE; then
    find "$WORK_DIR"/  -name \*group\*.mpg -exec cp -P {} "$BASEDIR" \;
fi
# carousel's are made BEFORE switched menus - so don't do them in switched mode
$SWITCHED_MODE && DO_CAROUSEL=false

# save value of default chapters
! $USER_CHAPTERS && (( ${#CHAPTERS[@]} == 1 )) && default_chapters=${CHAPTERS[0]}

# script details for the log file
PATTERN=$(for ((i=1; i<=79; i++)); do echo -n \*; done)
printf "%s\n%s\n%s\n\n\n" "$PATTERN" \
"todisc from the tovid suite ($TOVID_VERSION) - log for `date`" \
"$PATTERN" >> "$LOG_FILE"
# put the command line into the log file to aid debugging
printf  "%s\n%s\n" todisc "${args[@]}" | sed "s/    */ /g;s/^ *//" | fold -bs >> "$LOG_FILE"
# do some locale debugging
echo -e "\nYou are using the following locale settings:" >> "$LOG_FILE"
locale >>  "$LOG_FILE" 2>&1
echo >> "$LOG_FILE"

# check aspect ratios of infiles so thumbs are in aspect without -aspect passed
if [[ $MENU_NUM -eq 1 ]] && ! $TEXTMENU \
  && ((inc_files)) && [[ -z "$V_ASPECT" ]]; then
    yecho
    yecho "Determining aspect ratio of videos"
    for ((i=0; i<${#FILES[@]}; i++)); do
        ! $SINGLE_SLIDESHOW && yecho "Checking aspect ratios: ${FILES[i]}"
        stats[i]=$(idvid -terse -fast "${FILES[i]}" 2>/dev/null |
          awk -F= '/V_ASPECT_WIDTH=/ {print $2}' 2>/dev/null)
        cur_aspect=${stats[i]}
        if ((cur_aspect)); then
            [[ $cur_aspect = 133 ]] && ASPECT_RATIO=4:3
            [[ $cur_aspect = 177 ]] && ASPECT_RATIO=16:9
            yecho "Aspect ratio of $ASPECT_RATIO found.
            Videos in this menu (titleset) will be done using that ratio."
            ((cur_aspect==177||cur_aspect==133)) && break
        else
            yecho "No aspect ratio was determined.  Videos in ths menu
            (titleset) will be done using a ratio of 4:3"
        fi
done
    yecho
fi


################################################
#        recursive magic for titlesets,        #
# switched menus, and animated slideshow menus #
################################################

# if doing titlesets, call todisc recursively,
# collect parts and author.  Then exit
if $DO_TITLESETS; then
    titleset_mode "${args[@]}"
    yecho Goodbye
    exit
fi
# if -animated slideshow, AND  multiple slideshow or slideshow AND video(s)
# call todisc recursively for each ${FILES[@]},
# collect each concatenated carousel m2v, and exit
if { ((sshows>=1)) && ((inc_files >=1)) ; } || ((sshows>1)); then
    if $DO_CAROUSEL && ! $MK_CAROUSEL_MODE; then
        # call todisc recursively, collect slideshow.m2v and exit
        ! $CONFIRM_BACKUP && NO_CONFIRM_BACKUP="-no-confirm-backup"
        if ! carousel_menu_mode menu; then
            yecho '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
            yecho 'todisc encountered an error'
            cleanup && killall_instances
            exit 13
        fi
        if $CAROUSEL_IS_BG; then
            mv "$WORK_DIR/carousel-1.m2v" "$WORK_DIR/carousel-00.m2v"
            BACKGROUND="$WORK_DIR/carousel-00.m2v"
            BG_SEEK=0
        elif $CAROUSEL_IS_SHOWCASE; then
            mv "$WORK_DIR/carousel-1.m2v" "$WORK_DIR/carousel-00.m2v"
            SHOWCASE_FILE="$WORK_DIR/carousel-00.m2v"
            SHOWCASE_SEEK=0
        else
            for f in ${!FILES[@]}; do
                if ! ${SLIDESHOW[f]}; then
                    # set seek and chapter value if user only passed one value
                    [[ -z ${SEEK_VAL[f]} ]] && SEEK_VAL[f]=${SEEK_VAL[0]}
                    [[ -z ${CHAPTERS[f]} ]] && CHAPTERS[f]=$default_chapters
                elif ${SLIDESHOW[f]} && \
                 [[ -e $WORK_DIR/carousel-$((f+1)).m2v ]]; then
                    cp -v  "$WORK_DIR/carousel-$((f+1)).m2v" \
                    "$WORK_DIR/${TSET_NUM}-$((f+1)).mpg"
                    # use CAROUSEL array to id a do_not_overwrite symlink
                    CAROUSEL[f]="carousel"
                    if $SWITCHED; then
                        FILES[f]=$WORK_DIR/carousel-$((f+1)).m2v
                    else
                        FILES[f]=$WORK_DIR/${TSET_NUM}-$((f+1)).mpg
                    fi
                    SEEK_VAL[f]=0
                    CHAPTERS[f]=0
                fi
            done
        fi
        DO_CAROUSEL=false
    fi
fi
# if doing switched menus, call todisc recursively for each
# ${FILES[@]} and collect each intro.mpg
if $SWITCHED_MENUS; then
        switched_menu_mode "${args[@]}"
fi

######################################
#       end recursive calls          #
######################################


# if -slideshow-menu-thumbs passed, change with approprite FILE
if [[ -n ${SLIDESHOW_MENU_THUMBS[@]} ]]; then
    unset sld
    ((sshows < 1)) && \
     usage_error "You must be doing a slideshow to use -slideshow-menu-thumbs"
    for f in ${!FILES[@]}; do
        if ${SLIDESHOW[f]}; then # if this file is part of a slideshow...
            FILES[f]=${SLIDESHOW_MENU_THUMBS[sld++]} # replace it
        fi
    done
fi

# set some vars for the last run of switched menus (non-recursive )
$SWITCHED_MENUS && SHOWCASE_FILE=${FILES[0]}

yecho
yecho "Creating work directories"
yecho

# create an array of grouped files.
if $GROUPING; then
unset grp
for ((i=1; i<=${#FILES[@]}; i++)); do
    if [[ -n ${GROUP[i-1]} ]]; then
        for ((j=1; j<=${GROUP[i-1]}; j++)); do
            if [[ -e $WORK_DIR/${TSET_NUM}-group-${i}-${j}.mpg ]]; then
                grouping[grp++]=$WORK_DIR/${TSET_NUM}-group-${i}-${j}.mpg
            fi
        done
    fi
done
fi

# if no bg supplied, use template.png so we can add a frame (-quick-menu only)

# check that NTSC menu uses safe colours
if [[ $TV_STANDARD = "ntsc" ]]; then
    get_safe_colour $SFRAME_CLR && FRAME_CLR=$SAFE_CLR
    get_safe_colour $TITLE_CLR && TITLE_CLR=$SAFE_CLR
    get_safe_colour $SM_TITLE_CLR && SM_TITLE_CLR=$SAFE_CLR
    get_safe_colour $TITLE_STROKE && TITLE_STROKE=$SAFE_CLR
    get_safe_colour $SUBMENU_STROKE && SUBMENU_STROKE=$SAFE_CLR
    get_safe_colour $CHAPTER_STROKE && CHAPTER_STROKE=$SAFE_CLR
    get_safe_colour $TITLES_CLR && TITLES_CLR=$SAFE_CLR
    get_safe_colour $HLIGHT_CLR && HLIGHT_CLR=$SAFE_CLR
    get_safe_colour $SELECT_CLR && SELECT_CLR=$SAFE_CLR
    get_safe_colour $BG_CLR && BG_CLR=$SAFE_CLR
    get_safe_colour $TITLES_STROKE && TITLES_STROKE=$SAFE_CLR
    get_safe_colour $SUBMENU_BG_CLR && SUBMENU_BG_CLR=$SAFE_CLR
    get_safe_colour $THUMB_FRAME_CLR && THUMB_FRAME_CLR=$SAFE_CLR
    echo
    if [[ -n ${SUB_CLRS[@]} ]]; then
        echo "*** Note: ***"
        echo "Some of the colors you passed in are not NTSC color safe. "
        echo "The following substitutions were made for you:"
        for i in ${!SUB_CLRS[@]}; do
            echo "${SUB_CLRS[i]/:*} ===>  ${SUB_CLRS[i]/*:}"
        done
        echo "*************"
        echo
        $WARN && sleep 5
    fi
fi

if [[ -z $BACKGROUND ]]; then
    BACKGROUND="$WORK_DIR/bg.png"
    convert  -size $VIDSIZE! xc:$BG_CLR "$BACKGROUND"
fi
# check file type of background file and assign to BG_VIDEO or BG_IMAGE
if [[ -n $BACKGROUND ]]; then
    check_filetype "$BACKGROUND"
    if [[ $TYPE = "image" ]]; then
        BG_PIC="$BACKGROUND"
    elif [[ $TYPE = "video" ]]; then
        BG_VIDEO="$BACKGROUND"
    else
        usage_error "Sorry, can not identify "$BACKGROUND""
    fi
fi
if [[ -n ${SM_BACKGROUND[@]} ]]; then
    for smbg in ${!SM_BACKGROUND[@]}; do
        check_filetype "${SM_BACKGROUND[smbg]}"
        if [[ $TYPE != "image" ]]; then
            usage_error "-submenu-background takes image files only"
        fi
    done
fi

# if $SHOWCASE, find out if using SHOWCASE_VIDEO or SHOWCASE_IMG or ! SC_THUMB
if $SHOWCASE; then
    if [[ -n ${SHOWCASE_FILE[@]} ]]; then
        check_filetype "${SHOWCASE_FILE[@]}"
        if [[ $TYPE = "image" ]]; then
            SHOWCASE_IMG=${SHOWCASE_FILE[@]}
        elif [[ $TYPE = "video" ]]; then
            SHOWCASE_VIDEO=${SHOWCASE_FILE[@]}
        else
            usage_error "Can not identify showcase file: "${SHOWCASE_FILE[@]}""
        fi
    else
        SC_THUMB=false
        SHOWCASE_IMG="dummy"
    fi
fi
# find out the aspect ratio of the showcase file
if [[ -n $SHOWCASE_VIDEO ]]; then
    SC_AR=$(idvid -fast -terse "$SHOWCASE_VIDEO" 2>/dev/null |
    awk -F= '/V_ASPECT_WIDTH/ {print $2}' 2>/dev/null)
elif [[ -n $SHOWCASE_IMG && $SHOWCASE_IMG != "dummy" ]]; then
    SC_AR=$(identify -ping -format %wx%h "$SHOWCASE_IMG")
    SC_AR=$(bc_math "${SC_AR/x*} / ${SC_AR/*x}" )
fi

# now the showcase image is id'ed, we can find out what kind of quick menu
if $QUICK_MENU; then
    if [[ -n $SHOWCASE_VIDEO ]]; then
        QUICK_MENU_FILE="$SHOWCASE_VIDEO"
        QUICKMENU_IS_SHOWCASE=:
    elif [[ -n $BG_VIDEO ]]; then
        QUICK_MENU_FILE="$BG_VIDEO"
        QUICKMENU_IS_BACKGROUND=:
    fi
fi
if $QUICK_MENU && ! $QUICKMENU_IS_SHOWCASE && ! $QUICKMENU_IS_BACKGROUND; then
    if ! $SWITCHED; then
        yecho
        yecho "***** WARNING *****"
        if { $DO_TITLESETS || $TITLESET_MODE ; }; then
            yech=yecho
        else
            yech=usage_error
        fi
        if $is_carousel; then
            $yech "animated slideshows with quick-menu need either
            -background-slideshow  or -showcase-slideshow"
        else
            $yech "-quick-menu needs a -showcase VIDEO or a -background VIDEO"
        fi
        yecho "Disabling -quick-menu for you as it is not needed"
        yecho "It might be better to Ctrl-c now to exit and examine the situation
        as you are now making a showcase style menu"
        yecho
        QUICK_MENU=false
        # -quick-menu really messes up single slideshow
        if $SINGLE_SLIDESHOW; then
            BUTTON_STYLE="rect"
            SHOWCASE=false
        fi
        $WARN && sleep 10
    fi
fi
$QUICKMENU_IS_BACKGROUND && SHOWCASE_IMG=""
# some checks for -quick-menu
if $QUICK_MENU; then
# quick-menu needs TEXTMENU=: , and does its own showcase and bg with ffmpeg
    TEXTMENU=:
    SC_THUMB=false
    STATIC=: #FIXME
fi
if [[ $SC_FRAMESTYLE = "glass" ]] && [[ -z $SHOWCASE_IMG && -z $SHOWCASE_VIDEO ]]; then
    yecho
    yecho "You must use a -showcase option for '-showcase-framestyle'. Either "
    yecho "-showcase IMAGE, -showcase VIDEO, -showcase mix, or '-showcase'"
    yecho "Disabling this option for you - please exit now"
    yecho "if you wish to reexamine the situation"
    yecho
    SC_FRAMESTYLE="none"
fi
if [[ $SC_FRAMESTYLE = "glass" ]] && $QUICK_MENU; then
    yecho
    yecho "You can not use 'glass' frame style with -quick-menu, \
    disabling this option"
    yecho
    SC_FRAMESTYLE="none"
fi
# allow user to only specify one audio file for all submenus
if [ ${#SM_AUDIO[@]} -eq 1 ]; then
    if ((sshows>1)); then
        for i in ${!FILES[@]}; do
            SM_AUDIO[i]=${SM_AUDIO[0]}
        done
        unset SM_AUDIO_FILE
    else
        SM_AUDIO_FILE=${SM_AUDIO[0]}
    fi
fi
# if more than one audio file for submenu make sure they equal video #
if [[ ${SM_AUDIO[@]} && \
${#FILES[@]} -ne ${#SM_AUDIO[@]} &&  ${#SM_AUDIO[@]} -ne 1 ]]; then
    usage_error "Please give the same number of submenu audios as videos.
    You gave ${#FILES[@]} video files and ${#SM_AUDIO[@]} audio files"
fi
# Get absolute pathnames of all files
if ! $VMGM_ONLY; then
    for i in "${FILES[@]}"; do
        IN_FILES=("${IN_FILES[@]}" "$(readlink -f "$i")")
        (( ${#FILES[@]} < 12 )) && echo "Adding: $i" || spin "Adding: ${i##*/}"
    done
fi

$VMGM_ONLY && V_TOTAL=$(( ${#TITLES[@]} - 1 )) || V_TOTAL=${#IN_FILES[@]}
$VMGM_ONLY && NUM_FILES=$(( ${#TITLES[@]} - 1 )) || NUM_FILES=$((V_TOTAL - 1))
# slide mix sets MONTAGE_MENU to false
$DO_CAROUSEL && MONTAGE_MENU=false

# switch title position when appropriate so it doesn't get covered up
! $USER_TITLE_GEO && [[ $BUTTON_GRAVITY = *south* ]] && TITLE_GRAVITY="north"
if [[ $BUTTON_GRAVITY = *east* || $BUTTON_GRAVITY = *west* ]]; then
    ! $USER_GEO &&  XGEO=45 && YGEO=45
    ! $SHOWCASE && ! $USER_TITLE_GEO && TITLE_GRAVITY=north
fi
! $SHOWCASE && \
[[ $BUTTON_GRAVITY = "center" ]] && ! $USER_TITLE_GEO && TITLE_GRAVITY="north"

# dvdauthor stuff: make an array of possible vars for dvdauthor post calls
if $CHAIN_VIDEOS; then
    if [ -z "$post_play" ]; then
        for ((i=0; i<NUM_FILES; i++)); do
                POST_PLAY[i]=chain
            done
    else
        for j in $post_play; do
            if [[ $j = *-* ]]; then
                for ((i=${j/-*}; i<=${j/*-}; i++)); do
                    POST_PLAY[i-1]=chain
                done
            elif [[ $j != *[^0-9]* ]]; then
                POST_PLAY[j-1]=chain
            fi
        done
    fi
    echo
    for ((n=0; n<=NUM_FILES; n++)); do
        if [ "${POST_PLAY[n]}" = "chain" ]; then
            if [ $n -lt $NUM_FILES ]; then
                echo "video $((n+1)) will be chained with video $((n+2))"
            else
                echo "video $((n+1)) will be chained with video 1"
            fi
        fi
    done
    echo
fi
# make array, remove everything after and including 1st '+',
#CHAPTERS=( ${CHAPTERS%%+*} ) # in case of grouped chapters
# allow user to pass HH:MM:SS chapters
$USER_CHAPTERS && CHAPT_ARRAY=( ${CHAPTERS[@]} )
# if arbitrary grouped chapters passed, make an array of them
if $GROUPING && $USER_CHAPTERS; then
    for i in ${!IN_FILES[@]}; do
        if [[ -n ${GROUP[i]} ]]; then
            group_arbitrary_chapters[i]=${grouped_user_chapters[i]//+/ }
        else
            group_arbitrary_chapters[i]=""
        fi
    done
fi
# if treating each video as a chapter, use 1 chapter.  No playall allowed here
if $VIDEOS_ARE_CHAPTERS; then
    if [[ -n ${grouping[@]} ]]; then
        usage_error "-videos-are-chapters can not be used with -group"
    elif $SUB_MENU; then
        usage_error "-videos-are-chapters can not be used with submenus"
    elif $USER_CHAPTERS; then
        usage_error "HH:MM:SS chapters incompatible with -videos-are-chapters"
    else
         CHAPTERS=1 && PLAYALL=false
    fi
fi
# allow specifying one # of chapters for all videos if not given in HH:MM:SS
if [[ ${#CHAPTERS[@]} -eq 1 && -z ${CHAPT_ARRAY[@]} ]]; then
    for ((i=0; i<=NUM_FILES; i++)); do
        CHAPTERS[i]=${CHAPTERS[0]}
    done
fi
# make sure if -video-pause is given it equals the # of videos
if [[ -n ${VPAUSE[@]} && ${#VPAUSE[@]} -ne 1 ]]; then
    if [[ ${#VPAUSE[@]} -ne ${#IN_FILES[@]} ]]; then
        usage_error "# of -video-pause args must equal 1 or the # of videos"
    fi
fi
# make sure if -group-video-pause is given it equals the # of videos
if [[ -n ${GRP_VPAUSE[@]} && ${#GRP_VPAUSE[@]} -ne 1 ]]; then
    if [[ ${#GRP_VPAUSE[@]} -ne ${#grouping[@]} ]]; then
        usage_error "# of -video-pause args must equal 1 or the # of videos"
    fi
fi
# allow specifying one # for -video-pause
if [[ -n ${VPAUSE[@]} && ${#VPAUSE[@]} -eq 1 ]]; then
    for ((i=0; i<=NUM_FILES; i++)); do
        VPAUSE[i]=${VPAUSE[0]}
    done
fi
# allow specifying one # for -group-video-pause
if [[ -n ${GRP_VPAUSE[@]} && ${#GRP_VPAUSE[@]} -eq 1 ]]; then
for i in ${!grouping[@]}; do
    GRP_VPAUSE[i]=${GRP_VPAUSE[0]}
done
fi
# check # of -submenu-length args, and allow specifying 1 value for all videos
if $SUB_MENU \
&& ((${#SUBMENU_LEN[@]} != 1 && ${#SUBMENU_LEN[@]} != ${#IN_FILES[@]} )); then
usage_error "Give 1 submenu length for each video, or just 1 value for all"
fi
if $SUB_MENU && (( ${#SUBMENU_LEN[@]} == 1 )); then
if ! $DO_CAROUSEL; then
    for i in ${!IN_FILES[@]}; do
        SUBMENU_LEN[i]=${SUBMENU_LEN[0]}
    done
fi
fi

# use user passed -submenu-length for static submenus with audio
if $SUB_MENU && ! $ANI_SUB_MENU; then
if ! $DO_CAROUSEL; then
    for i in ${!IN_FILES[@]}; do
        if $USER_SUBMENU_LEN; then
            SUBMENU_AUDIOLEN[i]=${SUBMENU_LEN[i]}
        fi
    done
fi
fi


# if more than one value for CHAPTERS, make sure they equal video #
if $SUB_MENU &&  [[ ${#FILES[@]} -ne ${#CHAPTERS[@]} ]]; then
$USER_CHAPTERS && string="chapter point string" || string="chapter"
usage_error "Please give the same number of ${string}s as videos.
You gave ${#FILES[@]} video files and ${#CHAPTERS[@]} ${string}(s)"
fi
# get normal CHAPTERS VAR,i.e.: 'how many chapters'
# Check if 1st is 00:00:00 and all chapters have HH:MM:SS format
if $USER_CHAPTERS; then
    for i in ${!CHAPT_ARRAY[@]}; do
        unset newchapts
        [[ ${CHAPTERS[i]} != *:* ]] && usage_error \
        "for HH:MM:SS style chapters all video chapters must have this format"
        if [[ ${CHAPT_ARRAY[i]:0:8} != 00:00:00 ]];then
            usage_error \
            "The first chapter must be 00:00:00. ${IN_FILES[i]} \
            used ${CHAPT_ARRAY[i]}"
        fi
        # remove + sign and commas, count the number of chapters left
        str=$(sed 's/+/ /g;s/,/ /g' <<< ${CHAPTERS[i]})
        for substr in $str; do [[ $substr != 0 ]] && newchapts+=($substr); done
        CHAPTERS[i]=${#newchapts[@]}
    done
fi
# do not let user use -chapters 0 (-chapters 5 0 6)
for ((i=0; i<${#CHAPTERS[@]}; i++)); do
    if ((${CHAPTERS[i]} == 0)) && ! ${SLIDESHOW[i]}; then
        if ! $USER_CHAPTERS; then
            [[ -z ${GROUP[i]} ]] && usage_error \
            "-chapters 0 is only for grouped videos (each video is a chapter)"
            CHAPTERS[i]=$(( ${GROUP[i]} + 1 )) && nochapt[i]=1
        fi
    fi
done
echo

# if using chapter titles, they must equal the combined total for all files
if [[ -n ${CHAPTER_TITLES[@]} ]]; then
    total_chapters=$(awk_total <<< "${CHAPTERS[@]}")
    if (( ${#CHAPTER_TITLES[@]} !=  $total_chapters )); then
        usage_error "If using chapter titles you must supply a title for each
        chapter in each video.  You gave ${#CHAPTER_TITLES[@]} titles but
        have a total of $total_chapters chapters."
    fi
fi
# find out longest chapter value (number of chapters)
if $SUB_MENU; then
    for ((i=0; i<${#CHAPTERS[@]}; i++)); do
        chapt_val=${CHAPTERS[i]}
        [ -z "$MAX_CHAPTERS" ] || ((chapt_val > MAX_CHAPTERS)) \
        && MAX_CHAPTERS=$chapt_val && max_chapt_key=$i
        [ -z "$MIN_CHAPTERS" ]  || ((chapt_val < MIN_VAL)) \
        && MIN_CHAPTERS=$chapt_val && min_chapt_key=$i
    done
fi

# a quick way to allow user to make a dvd with no menus
if $NOMENU; then
    cd "$WORK_DIR"
    yecho
    yecho "Making a DVD with no menus"
    yecho "Identifying video files"
    check_compliance
    # link files in $WORK_DIR so an array with "$file $chapters" will work
    for i in "${!IN_FILES[@]}"; do
        ln -s "${IN_FILES[i]}" "$WORK_DIR/$(printf %03d%s%s $i .mpg)"
        idvid_stats[i]=$(idvid -terse "${IN_FILES[i]}" 2>/dev/null)
        # run mencoder to get the length if using arbitrary chapters
        if $USER_CHAPTERS; then
            chapter_points[i]=${CHAPT_ARRAY[i]}
        else
            if $VIDEOS_ARE_CHAPTERS; then
                : # we don't need file length or chapters if not making chapters
            else
                yecho "Getting video lengths"
                VID_LEN[i]=$(vid_length  "${IN_FILES[i]}" )
                chapter_points[i]=$(make_chapters ${VID_LEN[i]} ${CHAPTERS[i]} )
            fi
        fi
    done
    get_stats files
    IN_FILES=( $WORK_DIR/*.mpg ) 
    lastvid=${#IN_FILES[@]}
    nomenu_cmd=(dvdauthor -o )
    nomenu_cmd+=("$OUT_DIR")
    $VIDEOS_ARE_CHAPTERS && nomenu_cmd+=( -t ) # only want 1 "-t" if 1 pgc
    for i in ${!IN_FILES[@]}; do
        curvid=$((i+1)) # zero based array, we want for ex. file 1 not file 0
        # -videos-are-chapters needs no chapter points, else make them and jump
        if ! $VIDEOS_ARE_CHAPTERS; then
            yecho
            echo -e "Chapters for ${IN_FILES[i]}\n${chapter_points[i]}"
            nomenu_cmd+=(-t)
            nomenu_cmd+=(-c ${chapter_points[i]})
            if ((i != lastvid-1)); then # no jump on last video
                nomenu_cmd+=(-i "post=jump title $((curvid+1)) ;")
            fi
            nomenu_cmd+=( -f )
        fi
        nomenu_cmd+=("${IN_FILES[i]}")
    done
    yecho
    echo Running: "${nomenu_cmd[@]}" -o "$OUT_DIR" | format_output
    yecho
    "${nomenu_cmd[@]}" -o "$OUT_DIR" | tee -a "$LOG_FILE" 2>&1
    dvdauthor -o "$OUT_DIR" -T
    thanks_goodbye
    $BURN && burn_disc
    cleanup
    exit 0
fi

yecho "Creating pics directories..."
for ((i=0; i<=NUM_FILES; i++)); do
    mkdir -p "$REAL_WORK_DIR/pics/$i"
done
yecho "${#FILES[@]} pics directories created"
# textmenu is static unless there is an animated background or showcase video
if $TEXTMENU && [[ -z $SHOWCASE_VIDEO && -z $BG_VIDEO ]]; then STATIC=:; fi

{ $MENU_FADE || test -n "$BG_VIDEO" ; } && mkdir -v "$REAL_WORK_DIR/bg"
mkdir "$REAL_WORK_DIR/animenu"
if $ANI_SUB_MENU; then
    for ((i=0; i<MAX_CHAPTERS; i++)); do
        mkdir "$REAL_WORK_DIR/animenu/$i"
    done
fi
if $SUB_MENU && ! $ANI_SUB_MENU; then
    mkdir "$REAL_WORK_DIR/submenu"
fi
if [[ -n "$SHOWCASE_VIDEO" ]]; then
    mkdir "$REAL_WORK_DIR/showcase"
fi

# if more than one value for AUDIO_CHANNEL, make sure they equal video #
if [[ -n $AUDIO_CHANNEL ]] && \
[[ ${#FILES[@]} -ne ${#AUDIO_CHANNEL[@]} && ${#AUDIO_CHANNEL[@]} -ne 1 ]]; then
    usage_error "Please give the same number of audio channels as videos.  \
    You gave ${#FILES[@]} videos and ${#AUDIO_CHANNEL[@]} audio channel values"
fi
# make sure number of -rotate-thumbs arguments equals number of videos
if $ROTATE_THUMBS; then
    if  [[ ${#FILES[@]} -ne ${#ROTATE_ARRAY[@]} ]]; then
        usage_error "Please give the same number of thumb rotate values \
        as videos.  You gave  ${#FILES[@]} video files and \
        ${#ROTATE_ARRAY[@]} thumb rotate values."
    fi
fi
# if  -wave passed, usage error if -showcase-shape also passed
#if [[ -n $WAVE && -n $SHOWCASE_SHAPE ]]; then
#    usage_error "You can not use both -wave and a -showcase-shape"
#fi

# if Fading menu, and no BG IMAGE OR VIDEO, fade thumbs right in after title
if $MENU_FADE; then
    # some vars for when we source todisc-fade-routine
    [[ -z "$BG_PIC" && -z "$BG_VIDEO" ]] &&  THUMBS_FADEIN_STARTTIME=2.5
    TITLE_FADEIN_STARTTIME=${TRANSITION_TO_MENU_LEN:-1}
    THUMBS_FADEIN_STARTTIME=$(bc_math "$TITLE_FADEIN_STARTTIME + 2.5")
    # if user did not pass in -loop value, set pause to 'inf'
    if $USER_LOOP && [[ $PAUSE_TIME = "inf" ]]; then
        TITLE_FADEOUT_ENDTIME=${MENU_LEN[MENU_NUM-1]}
        TITLE_FADEOUT_STARTTIME=${MENU_LEN[MENU_NUM-1]}
        THUMBS_FADEOUT_ENDTIME=${MENU_LEN[MENU_NUM-1]}
        THUMBS_FADEOUT_STARTTIME=${MENU_LEN[MENU_NUM-1]}
        BG_FADEOUT_STARTTIME=${MENU_LEN[MENU_NUM-1]}
    fi
fi

# if only one seek value, then use for all videos
if [ ${#SEEK_VAL[@]} -eq 1 ]; then
    for ((i=0; i<=NUM_FILES; i++)); do
        SEEK_VAL[i]=${SEEK_VAL[0]}
        SEEK[i]="-ss ${SEEK_VAL[i]}" # create seek value for each video
    done
fi
# if only one chapters fontsize, then use for all videos
if ((${#CHAPT_FONTSIZE[@]} == 1 )); then
    for ((i=0; i<=NUM_FILES; i++)); do
        CHAPT_FONTSIZE[i]=${CHAPT_FONTSIZE[0]}
    done
fi
# make sure if more than one chapter fontsize, they equal the number of videos
if ! $VMGM_ONLY && [[ -n $CHAPT_FONTSIZE ]] \
&& ((${#FILES[@]} != ${#CHAPT_FONTSIZE[@]})); then
    usage_error "Please give the same number of seek times as videos,
    or just use one value.  You gave ${#FILES[@]} video files
    and ${#CHAPT_FONTSIZE[@]} seek times"
fi
# allow -seek to have HH:MM:SS format passed
for ((i=0; i<=NUM_FILES; i++)); do
    if [[ "${SEEK_VAL[i]}" = *:* ]]; then
        SEEK_VAL[i]=$(unformat_time ${SEEK_VAL[i]})
    fi
done
# make sure if more than one seek value, they equal the number of video
if ! $VMGM_ONLY &&  ((${#FILES[@]} != ${#SEEK_VAL[@]})); then
    usage_error "Please give the same number of seek times as videos, or \
    just use one value.  You gave ${#FILES[@]} video files and \
    ${#SEEK_VAL[@]} seek times"
fi
# if more than 1 -menu-length value passed, total must be same as videos total
if ! $VMGM_ONLY &&  ((${#FILES[@]} != ${#MENU_LEN[@]})); then
    usage_error "Please give the same number of -menu-length times as
    videos, or just use one value.  You gave ${#FILES[@]} video files
    and ${#MENU_LEN[@]} -menu-length times"
fi
# set a maximum # of videos
if $SHOWCASE && ! $MK_CAROUSEL_MODE; then
    $TEXTMENU && file_max=26 || file_max=10
    test  ${#FILES[@]} -gt $file_max && usage_error \
     "Sorry, a maximum of $file_max titles is allowed for this style
    You gave ${#FILES[@]} videos as input"
else
    if test ${#FILES[@]} -gt 36; then
        ! $SINGLE_SLIDESHOW && usage_error \
         "Sorry, a maximum of 36 videos (thumbs) is supported
         You gave ${#FILES[@]} files as input.  Please use titlesets
         for this many files.  Alternatively you may use '-group' to group
        some of them under a single button"
    fi
fi

if ! $VMGM_ONLY; then
    # two values for length of video(frames) and audio(secs) for slides
    # SVCD mpegs are minumum length of 4 seconds, DVD can be just single frame
    # this is a hack since makexml is broken for svcd stills
    vlength=4
    alength=$(bc_math "4 / $FRAME_RATE") # 0.16 or 0.133
    # float < 1  must begin with 0
    [[ -n ${alength/*.} && -z ${alength/.*} ]] && alength=0${alength}
    echo
    echo "Verifying that input files are video or image files"
    verify_infiles infiles
    if [[ ${#file_is_image[@]} -eq ${#FILES[@]} && $inc_files -gt 0 ]]; then
        usage_error "Please use -slides IMAGES, not -files IMAGES
        for a slideshow"
    fi
    if $GROUPING; then
        echo
        echo "Verifying that grouped input files are video or image files"
        verify_infiles group
        echo
    fi
    echo
fi
echo
# some vars for slide mix
# this is only called when todisc running recursively to make ani slideshows
# DO_CAROUSEL is set to false when the self recursion is complete
# this happens earlier in the script.
if $DO_CAROUSEL; then
    if [[ -n ${GROUP[@]} ]] && ! $MK_CAROUSEL_MODE; then
        #*slide_grp*.mpg are symlinks to the original images we have kept intact
        mixgroup=( "$WORK_DIR"/${TSET_NUM}-slide_grp-*.mpg )
        for g in ${!mixgroup[@]}; do
            MIXFILES[g]=$(readlink -f "${mixgroup[g]}")
            MIXLINKS[g]=${mixgroup[g]}
            # remove original link we can keep track of what is already encoded
            rm -f "${MIXLINKS[g]}"
        done
    else
        MIXFILES=( "${IN_FILES[@]}" )
    fi
    for n in ${!BLURFILES[@]}; do
        for i in ${!MIXFILES[@]}; do
            if [[ ${MIXFILES[i]##*/} = ${BLURFILES[n]##*/} ]]; then
                blur_files[i]=${MIXFILES[i]}
                SLIDE_BLUR_AMT[i]=${SLIDE_BLUR_OPT[n]}
            fi
        done
    done
   # randomize order to produce the final 'mix'
    for f in "${!MIXFILES[@]}"; do
        a=$RANDOM
        while [[ ${shuffled[a]} ]]; do
            a=$RANDOM
        done
        shuffled[a]=${MIXFILES[f]}
        if [[ ${SLIDE_BLUR_AMT[f]} ]]; then
            SHUFFLED_SLIDE_BLUR[a]="-blur ${SLIDE_BLUR_AMT[f]}"
        else
            SHUFFLED_SLIDE_BLUR[a]="none"
        fi
    done
    # remove holes in the array and reassign to MIXFILES
    MIXFILES=( "${shuffled[@]}" )
    SLIDE_BLUR=( "${SHUFFLED_SLIDE_BLUR[@]}" )
    unset r
    for s in ${!SLIDE_BLUR[@]}; do
        [[ ${SLIDE_BLUR[s]} = "none" ]] && unset SLIDE_BLUR[s]
    done
fi
[[ -n $MIX_RANGE ]] && MIXRANGE=$MIX_RANGE
#[[ -n $SM_MIX_RANGE ]] && MIXRANGE=$SM_MIX_RANGE
if [[ -n $MIXRANGE ]] && ((MIXRANGE<${#MIXFILES[@]})); then
    last_ind=$MIXRANGE
    for ((i=0; i<MIXRANGE; i++)); do
        #[[ -n ${SLIDE_BLUR[i]} ]] &&
        if $DO_CAROUSEL; then
            MIX_IN=( "${MIX_IN[@]}" "${MIXFILES[i]}" )
        else
            # read in in reverse order so 1st slide is composited last
            MIX_IN=( "${MIX_IN[@]}" "${IN_FILES[--last_ind]}" )
        fi
    done
else
    if $DO_CAROUSEL; then
        MIX_IN=( "${MIXFILES[@]}" )
    else
        last_ind=${#IN_FILES[@]}
        for i in ${!IN_FILES[@]}; do
            MIX_IN[i]=${IN_FILES[--last_ind]}
        done
        #MIX_IN=( "${IN_FILES[@]}" )
    fi
fi
# All files must be images for slide mix.
# if all are images, then we are doing a slideshow.
echo
if $SINGLE_SLIDESHOW; then
    # if -static was not passed we have already set DO_CAROUSEL to :
    # So here we set STATIC to : as ani slideshow has its own code
    DO_FRAME=false; DO_BUTTONS=false; STATIC=:; DO_STATS=false
    CAROUSEL_IS_SHOWCASE=false
    CAROUSEL_IS_BG=false
    [[ $MENU_TITLE = "My Video Collection" ]] && \
    MENU_TITLE="My Slideshow"
fi
# don't print stats when slideshows are being done
((sshows>=1)) && DO_STATS=false

# no playall for single slideshow, and it has its own menu block, not DO_MENU
if $SINGLE_SLIDESHOW ; then
    PLAYALL=false
    ! $MONTAGE_MENU && DO_MENU=false
fi

# for slides or short files, seeking/fading will not work: set them to 0
# if user has not set a value from the command line
for i in ${!IN_FILES[@]}; do
    SHORTFILE=false
    if [[ ${file_is_image[i]} = "yes" ]]; then
        SHORTFILE=:
    else
        FRAME_CK=$(vid_length "${IN_FILES[i]}" 90)
        [[ $(bc -l <<< "$FRAME_CK < 2") -eq 1 ]] && SHORTFILE=:
    fi
    if $SHORTFILE; then
        ! $USER_SEEK_VAL && SEEK_VAL[i]=0
        ! $USER_CHAPTERS && CHAPTERS[i]=1
    fi
done
if [[ $FADE -eq 0 ]]; then # in case user thinks he needs to specify 0 for fade
    AUDIO_FADE=false
elif [[ $SM_FADE -eq 0 ]]; then
    SM_AUDIO_FADE=false
fi


##############################################################################
# Font defaults
##############################################################################

if $DO_MENU; then
    # Menu title font size
    test $TARGET = "dvd" && : ${MENU_FONTSIZE:="30"}
    # Thumbnail title font size
    # if not -titles-fontsize N passed, use default, based on the following:
    if test -z "$TITLES_FONTSIZE"; then
        if test "$NUM_FILES" -lt 2; then
            TITLES_FONTSIZE=20
        elif  test "$NUM_FILES" -eq 2; then
            TITLES_FONTSIZE=18
        elif  test "$NUM_FILES" -ge 3; then
            TITLES_FONTSIZE=16
        fi
    fi
    if test -z $CHAPT_FONTSIZE; then
        for c in ${!IN_FILES[@]}; do
            ((${CHAPTERS[c]} <= 2)) && CHAPT_FONTSIZE[c]=20
            ((${CHAPTERS[c]} == 2)) && CHAPT_FONTSIZE[c]=18
            ((${CHAPTERS[c]} >= 2)) && CHAPT_FONTSIZE[c]=16
        done
    fi
    test -z $SUBMENU_FONTSIZE && SUBMENU_FONTSIZE=$MENU_FONTSIZE

    # See if "Helvetica" or "helvetica" are available as default fonts
    if convert -size 50x20 xc:none -font Helvetica -gravity Center \
    -draw "text 0,0 'test'" "$WORK_DIR/font.png"; then
        DEFAULT_FONT="Helvetica"
    elif convert -size 200x100 xc:none -font helvetica -gravity Center \
    -draw "text 0,0 'test'" "$WORK_DIR/font.png"; then
        DEFAULT_FONT="helvetica"
    fi
    # If user did not specify fonts, use default
    test -z "$MENU_FONT" && MENU_FONT=$DEFAULT_FONT
    test -z "$TITLES_FONT" && TITLES_FONT=$DEFAULT_FONT
    test -z "$CHAPT_FONT" && CHAPT_FONT="$TITLES_FONT"
    test -z "$SM_TITLE_FONT" && SM_TITLE_FONT="$MENU_FONT"
    rm -f "$WORK_DIR/font.png"

    # Some user feedback
    if ! $SINGLE_SLIDESHOW; then
        yecho
        if $VMGM_ONLY; then
            yecho "Disc title: \"$MENU_TITLE\""
        else
            yecho "Menu title: \"$MENU_TITLE\""
        fi
        yecho "  (adjust with -menu-title)"
        yecho "Including the following files:"
        # do not echo all of long or multiline titles AND files
        for ((i=0; i<${#TITLES[@]}; i++)); do
            if [[ ${#TITLES[i]} -gt 35 || \
            $(echo -e "${TITLES[i]}" |wc -l) -gt 1 ]]; then
                TITLE[i]=$(sed 's/^  *//'<<<${TITLES[i]//\\n/ }) # no spaces or \n
                TITLE[i]=${TITLE[i]:0:35} # cut down to 35 characters maximum
                if [ ${#TITLES[i]} -gt 35 ]; then
                    echo "  \"${TITLE[i]}...\" (${IN_FILES[i]})" # "..."
                else
                    echo "  \"${TITLE[i]}\" (${IN_FILES[i]})"
                fi
            else # echo titles "as is"
                echo "  \"${TITLES[i]}\" (${IN_FILES[i]})"
            fi
            if [[ $(echo -e "${TITLES[i]}" |wc -l) -gt 1 ]]; then
                # if there is a multiline title we need to align to right of thumbs
                SC_TITLE_ALIGN=east
                ALIGN_OVERRIDE=:
            fi
        done
        yecho "Current font settings: "
        yecho "  -menu-font $MENU_FONT"
        yecho "  -menu-fontsize $MENU_FONTSIZE"
        yecho "  -titles-font $TITLES_FONT"
        yecho "  -titles-fontsize $TITLES_FONTSIZE"
        if ! $VMGM_ONLY; then
            yecho "Current menu settings: "
            if  ! $STATIC; then
                yecho "  -menu-length ${MENU_LEN[MENU_NUM-1]} seconds"
            fi
            if $ANI_SUB_MENU; then
                if $USER_SUBMENU_LEN; then
                    for i in ${!SUBMENU_LEN[@]}; do
                        sml=${SUBMENU_LEN[i]}
                        yecho "Video $((i+1)):  -submenu-length $sml seconds"
                    done
                else
                        yecho "  -submenu-length $SUBMENU_LEN seconds"
                fi
                if $SUBMENU_AUDIO; then
                    yecho "  -submenu-audio-fade $SM_FADE second(s)"
                fi
            fi
                for ((i=0; i<=NUM_FILES; i++)); do
                    echo -n "Video $((i+1)):"
                    echo -n "  -seek ${SEEK_VAL[i]} second(s)"
                    echo "  -chapters ${CHAPTERS[i]}"
                done
            if [ ! $STATIC ]; then
                yecho "  -menu-audio-fade $FADE second(s)"
            fi
            yecho
        fi
    fi
fi
# TODO: Merge these globals with the ones up top
# only the 1st 6 are mergable - keeping them here for debugging this beast :)
# 9 /row
NTSC_1333_DVD=(420x280 300x200 192x128 192x128 186x124 186x124 132x88 132x88 \
132x88 120x80 120x80 120x80 96x64 96x64 96x64 96x64 96x64 96x64 \
96x64 96x64 84x56 84x56 84x56 84x56 84x56 84x56 84x56 \
84x56 84x56 84x56 60x40 60x40 60x40 60x40 60x40 60x40 \
60x40 60x40 60x40 60x40 60x40 60x40 60x40 60x40 60x40
60x40 60x40 60x40 60x40)
# *_1777_DVD is for 16:9 videos displayed in proper res on a 4:3 menu
NTSC_1777_DVD=(420x210 300x150 240x120 240x120 186x98 186x98 180x90 180x90 \
180x90 132x66 132x66 132x66 132x66 132x66 132x66 132x66 100x50 100x50 \
100x50 100x50 100x50 100x50 100x50 100x50 100x50 88x44 88x44 \
88x44 88x44 88x44 80x40 80x40 80x40 80x40 80x40 80x40)
PAL_1333_DVD=(420x336 300x240 190x152 190x152 190x152 190x152 130x104 130x104 \
130x104 130x104 130x104 130x104 100x80 100x80 100x80 100x80 100x80 100x80 \
100x80 100x80 90x72 90x72 90x72 90x72 90x72 90x72 90x72 \
90x72 90x72 90x72 60x48 60x48 60x48 60x48 60x48 60x48)
PAL_1777_DVD=(420x252 300x180 240x144 240x144 190x114 190x114 190x114 190x114 \
190x114 130x78 130x78 130x78 130x78 130x78 130x78 130x78 100x60 100x60
100x60 100x60 100x60 100x60 100x60 100x60 100x60 90x54 90x54 90x54 90x54 90x54
80x48 80x48 80x48 80x48 80x48 80x48)
# 15 per row
TILE_1333=(1x1 2x1 2x2 2x2 3x2 3x2 3x3 3x3 3x3 4x3 4x3 4x3 4x4 4x4 4x4 \
4x4 5x4 5x4 5x4 5x4 5x5 5x5 5x5 5x5 5x5 6x5 6x5 6x5 6x5 6x5 \
6x6 6x6 6x6 6x6 6x6 6x6)
TILE_1777=(1x1 2x1 2x2 2x2 3x2 3x2 3x3 3x3 3x3 4x3 4x3 4x3 4x4 4x4 4x4 \
4x4 5x4 5x4 5x4 5x4 5x5 5x5 5x5 5x5 5x5 5x6 5x6 5x6 5x6 5x6 \
6x6 6x6 6x6 6x6 6x6 6x6)
SC_THUMB_Y_ARRAY=("166" "110 240" "75 175 275" "68 148 228 308" \
"68 131 194 257 320" "75 175 275 75 175 275" "68 148 228 308 68 148 228" \
"68 148 228 308 68 148 228 308" "68 131 194 257 320 68 131 194 257" \
"68 131 194 257 320 68 131 194 257 320")
SC_TITLES_Y_ARRAY=("144" "88 218" "54 154 254" \
"50 130 210 290" "49 112 175 238 301" "54 154 254 54 154 254" \
"50 130 210 290 50 130 210" "50 130 210 290 50 130 210 290" \
"49 112 175 238 301 49 112 175 238" \
"49 112 175 238 301 49 112 175 238 301")
SC_THUMB_X_ARRAY=("86" "86 86" "86 86 86" "86 86 86 86" \
"86 86 86 86 86" "86 86 86 538 538 538" "86 86 86 86 554 554 554" \
"86 86 86 86 554 554 554 554" "86 86 86 86 86 574 574 574 574" \
"86 86 86 86 86 574 574 574 574 574")
SC_THUMB_X_ARRAY=( ${SC_THUMB_X_ARRAY[NUM_FILES]} )
SC_THUMB_Y_ARRAY=( ${SC_THUMB_Y_ARRAY[NUM_FILES]} )
SC_TITLES_X_ARRAY=( ${SC_THUMB_X_ARRAY[@]} )
SC_TITLES_Y_ARRAY=( ${SC_TITLES_Y_ARRAY[NUM_FILES]} )
if $TEXTMENU ; then
    ! $USER_SPLIT && SPLIT=13 # max text only titles in one column (-textmenu)
    if [[ $NUM_FILES -gt 12 ]] && ! $USER_SPLIT; then
        SPLIT=$((V_TOTAL / 2))
        [[ $(( SPLIT * 2)) -ne $V_TOTAL ]] && let SPLIT=SPLIT+1
    fi
#for ((b=0; b<=NUM_FILES; b++)); do
#((b < SPLIT)) && SC_TITLES_X_ARRAY[b]=86||SC_TITLES_X_ARRAY[b]=360
#done
fi
# needed to centre showcase img: col 1 will always be larger value than col 2
if $SHOWCASE && ! $TEXTMENU; then
    ((NUM_FILES < 5)) && SPLIT=$((NUM_FILES+1))
    ((NUM_FILES == 5)) && SPLIT=3
    ((NUM_FILES >= 6)) && SPLIT=4
    ((NUM_FILES >= 8)) && SPLIT=5
fi
# Montage geometry: closer together for large arrangements
AUDIO_EXT="ac3"
SAMPLERATE="48000"
MPLEX_FORMAT="8"
FFMPEG_OPTS="-b 7000k  -maxrate 8000k -bufsize 224KiB -aspect 4:3"
SS_FFMOPTS="-b 8000k -maxrate 9000k -bufsize 224KiB -aspect 4:3"
ASPECT="-aspect $ASPECT_RATIO"
SHOWCASE_SIZE=384x256
BURN_TGT="$OUT_DIR"
BURN_TGT_STR="DVD directory"
BURN_PROG="makedvd"
if [ $TV_STANDARD = "ntsc" ]; then
    if [[ $ASPECT_RATIO = "4:3" ]]; then
        GEO_ARRAY=("${NTSC_1333_DVD[@]}")
        TILE_ARRAY=("${TILE_1333[@]}")
    else
        GEO_ARRAY=("${NTSC_1777_DVD[@]}")
        TILE_ARRAY=("${TILE_1777[@]}")
    fi
    VIDSIZE="720x480"
    FRAME_RATE=29.970
    if [[ $SC_AR = 133 ]]; then
        SHOWCASE_SIZE=384x256
        SM_SHOWCASE_SIZE=288x192
    elif [[ $SC_AR = 177 ]]; then
        SHOWCASE_SIZE=384x192
        SM_SHOWCASE_SIZE=288x144
    fi
elif [ $TV_STANDARD = "pal" ]; then
    VIDSIZE="720x576"
    TILE_ARRAY=("${TILE_1333[@]}")
    FRAME_RATE=25
    if [[ $SC_AR = 133 ]]; then
        SHOWCASE_SIZE=380x304
        SM_SHOWCASE_SIZE=290x232
    elif [[ $SC_AR = 177 ]]; then
        SHOWCASE_SIZE=384x230
        SM_SHOWCASE_SIZE=290x174
    fi
    if [[ $ASPECT_RATIO = "4:3" ]]; then
        GEO_ARRAY=("${PAL_1333_DVD[@]}") #TODO make sizes array for pal
    else
        GEO_ARRAY=("${PAL_1777_DVD[@]}")
    fi
fi
if [[ $TV_STANDARD = "ntsc" ]]; then
    YUV_FR=30000:1001
else
    YUV_FR=25:1
fi
THUMB_SIZE=${GEO_ARRAY[NUM_FILES]}
if $SHOWCASE; then
    if [ -z ${BLUR/.*} ]; then
        BLUR=0.${BLUR/*.}
    fi
    if (( ${BLUR/.*} > 2 )) && [[ -n $THUMB_SHAPE ]]; then
        BLUR=2.0
        if ! $TEXTMENU; then
            yecho
            yecho "Reducing thumb blur to 2.0 because you are using -showcase"
            yecho
            $WARN && sleep 3
        fi
    fi
    if [ $V_TOTAL -lt 3 ]; then
        THUMB_SIZE=${GEO_ARRAY[10]}
    elif [ $V_TOTAL -eq 3 ]; then
        THUMB_SIZE=${GEO_ARRAY[13]}
    elif [ $V_TOTAL -eq 4 ]; then
        THUMB_SIZE=${GEO_ARRAY[23]}
    elif [ $V_TOTAL -eq 5 ]; then
        THUMB_SIZE=${GEO_ARRAY[30]}
    elif [ $V_TOTAL -eq 6 ]; then
        THUMB_SIZE=${GEO_ARRAY[13]}
    elif [[ $V_TOTAL -ge 7 && $V_TOTAL -le 8 ]]; then
        THUMB_SIZE=${GEO_ARRAY[23]}
    elif [[ $V_TOTAL -ge 9 && $V_TOTAL -le 10 ]]; then
        THUMB_SIZE=${GEO_ARRAY[30]}
    fi
fi

#create seek value for each video
for ((i=0; i<=NUM_FILES; i++)); do
    # translate SEEK_VAL into frames for transcode
    SEEK_FRAMES[i]=$(bc_math "${SEEK_VAL[i]} * $FRAME_RATE" int)
done

# some choices needed for different title alignments
if $SHOWCASE && ! $TEXTMENU; then
    if [ $V_TOTAL -le 5 ]; then
        if [[ $SC_TITLE_ALIGN = "east" ]]; then
            SHOWCASE_SIZE=$SM_SHOWCASE_SIZE  # smaller to allow for titles
        fi
        AUTOORDER="rows"       # spumux var
    else
        SHOWCASE_SIZE=$SM_SHOWCASE_SIZE  # smaller showcase thumb because we have 2 rows
        AUTOORDER="columns"
        if $SC_THUMB && \
        [[ "$SC_TITLE_ALIGN" = "east" ]] && [[ -n $SHOWCASE_FILE ]]; then
            usage_error "Sorry, there is no room for the showcase thumb " \
            "if you use more than 5 videos with -showcase-titles-align " \
            "east|west (also multiline titles). Either change the problem " \
            "option, remove the showcase image/video, or use -textmenu.  Or " \
            "consider using -bgimage or -bgvideo instead of a showcase thumb."
        fi
    fi
elif ! $SHOWCASE && ! $TEXTMENU; then
    AUTOORDER="rows"
elif $TEXTMENU; then
    AUTOORDER="columns"
fi

# set size of animated slideshow menu images
if $CAROUSEL_IS_BG; then
    CAROUSEL_SIZE=$VIDSIZE
else
    # use SHOWCASE_SIZE instead of THUMBSIZE for better quality,
    # even though for video thumbs it gets resized later
    CAROUSEL_SIZE=$SHOWCASE_SIZE
fi
$SINGLE_SLIDESHOW && ! $MK_CAROUSEL_MODE && CAROUSEL_SIZE=$VIDSIZE

$TEXTMENU && LEFT_MAX=$SPLIT || LEFT_MAX=5
if [ "$SC_TITLE_ALIGN" = "west" ] || $TEXTMENU; then #FIXME
    THUMB_TITLE_ALIGN="west" # for non TEXTMENU menu
    for ((i=0; i<=NUM_FILES; i++)); do
        if [ $i -lt $LEFT_MAX ]; then
            SC_THUMB_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - \
            SAFE_OFFSET ))
            SC_TITLES_X_ARRAY[i]=$(( ${SC_TITLES_X_ARRAY[i]} - \
            SAFE_OFFSET ))
        fi
        if ! $TEXTMENU && ! [[ $SHOWCASE_FILE ]]; then
            if (( ${SC_THUMB_X_ARRAY[i]} > ( ${VIDSIZE/x*} / 2 ) )); then
                SC_THUMB_X_ARRAY[i]=$(( ${VIDSIZE/x*} / 2 ))
                SC_TITLES_X_ARRAY[i]=$(( ${VIDSIZE/x*} / 2 ))
            fi
        fi
    done
fi
# centre aligned titles are not for textmenu style
if $TEXTMENU && [[ $SC_TITLE_ALIGN = "center" ]]; then
    yecho
    yecho "Sorry, you can not use center align for textmenu titles"
    yecho "Using title alignment of 'west': please check the preview"
    yecho
    SC_TITLE_ALIGN="west"
    $WARN && sleep 10
fi
#  -align east uses text-rect
if [[ $BUTTON_STYLE = "text-rect" ]] \
 && ! [[ $SC_TITLE_ALIGN = "east" ]] && $SHOWCASE && ! $TEXTMENU; then
    yecho "***Warning***"
    yecho "text-rect buttons need to be aligned east of thumbs:  by using:"
    yecho " '-showcase-titles-align east'"
    yecho "Setting this option for you"
    yecho "Ctrl-c now to exit if you wish to reconsider"
    SC_TITLE_ALIGN="east"
    yecho
    $WARN && sleep 10
fi
if $SHOWCASE && [ "$SC_TITLE_ALIGN" = "east" ] && ! $TEXTMENU; then
    THUMB_TITLE_ALIGN="west" # align titles left to allow longer titles
    for ((i=0; i<=NUM_FILES; i++)); do
        if [ $i -lt $LEFT_MAX ] && ! $ALIGN_OVERRIDE; then
            SC_THUMB_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - \
            SAFE_OFFSET ))
            SC_TITLES_X_ARRAY[i]=$(( ${SC_TITLES_X_ARRAY[i]} - \
            SAFE_OFFSET ))
        fi
        if [ ${SC_THUMB_X_ARRAY[i]} -gt 360 ]; then
            SC_THUMB_X_ARRAY[i]=360
        fi
        SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} + \
        ${THUMB_SIZE/x*} + 5 ))
        #SC_TITLES_Y_ARRAY[i]=$(( ${SC_TITLES_Y_ARRAY[i]} + 18 ))
        SC_TITLES_Y_ARRAY[i]=${SC_THUMB_Y_ARRAY[i]} # DEBUG:why not originally?
    done
fi
if { $USER_GRAVITY && $SHOWCASE && ! $TEXTMENU ; } \
              && [[ $BUTTON_GRAVITY != north ]]; then
    SW_CORNER=$(( ${SC_THUMB_Y_ARRAY[SPLIT-1]} + ${THUMB_SIZE/*x} ))
    if [[ $BUTTON_GRAVITY = *south* ]]; then
        Y_OFFSET=$(( ( ${VIDSIZE/*x} - SAFE_AREA) - SW_CORNER ))
    elif [[ $BUTTON_GRAVITY = *st* ]] || [[ $BUTTON_GRAVITY = *center* ]]; then
        COL1_HEIGHT=$(( SW_CORNER - ${SC_TITLES_Y_ARRAY[0]} ))
        Y_OFFSET=$(( ( ${VIDSIZE/*x} / 2) - (COL1_HEIGHT / 2) ))
        Y_OFFSET=$(( Y_OFFSET - ${SC_TITLES_Y_ARRAY[0]} ))
    fi
    for ((i=0; i<=NUM_FILES; i++)); do
        SC_THUMB_Y_ARRAY[i]=$((${SC_THUMB_Y_ARRAY[i]} + Y_OFFSET ))
        SC_TITLES_Y_ARRAY[i]=$((${SC_TITLES_Y_ARRAY[i]}+ Y_OFFSET))
    done
fi
# default for showcase style is left justification, for montages: center
$SHOWCASE && JUSTIFY="west" || JUSTIFY="center"
# find out the showcase thumb "-page" array for this arrangement
for ((i=0; i<=NUM_FILES; i++)); do
    if $TEXTMENU; then
        SCTHUMB_PAGES_ARRAY[i]=+${SC_TITLES_Y_ARRAY[i]}+${SC_TITLES_X_ARRAY[i]}
    else
        SCTHUMB_PAGES_ARRAY[i]=+${SC_THUMB_X_ARRAY[i]}+${SC_THUMB_Y_ARRAY[i]}
    fi
done

# Do everything in $WORK_DIR
echo -e "**** NOTE ****\n"
echo "Doing all work in directory $REAL_WORK_DIR"
echo "$WORK_DIR will be a symlink pointing to this directory"
echo -e "\n**************"
$WARN && sleep 1
cd "$WORK_DIR"

# default of no blur if using 3D thumbs or flare shape
if $THUMBS_3D; then
    BLUR=0.1
fi
if ! ((USER_BLUR)) && [[ $THUMB_SHAPE == "flare" ]]; then
    BLUR=0.1
fi
if ! ((SC_USER_BLUR)) && [[ $SHOWCASE_SHAPE == "flare" ]]; then
    SC_BLUR=0.1
fi
# no 3d thumbs for flare shape
if $THUMBS_3D || $SHOWCASE_3D && \
  [[ $THUMB_SHAPE == "flare" || $SHOWCASE_SHAPE == "flare" ]]; then
    warning_message "There is no 3d thumbs available for the 'flare' shape. "
    "Disabling this option for you"
    $WARN && sleep 3
fi

$FOURxONE && $SHOWCASE && FOURxONE=false && tile_warning
$THREExONE && $SHOWCASE && THREExONE=false && tile_warning
# allow specifically setting the geometry for 3 videos to 1x3 page
if $THREExONE || $FOURxONE; then
    if $THREExONE && [ $V_TOTAL -eq 3 ]; then
        TILE_ARRAY[2]=3x1
        [[ $ASPECT_RATIO = "16:9" ]] && THUMB_SIZE=${GEO_ARRAY[4]}
    elif $FOURxONE && [[ $V_TOTAL -eq 4 ]]; then
        TILE_ARRAY[3]=4x1
        if  [[ $ASPECT_RATIO = "16:9" ]]; then
            THUMB_SIZE=${GEO_ARRAY[9]}
        else
            THUMB_SIZE=${GEO_ARRAY[6]}
        fi
    else
        warning_message "Warning: Incorrect number of videos for ${tile_arg}:
        this option will be ignored"
        $WARN && sleep 3
    fi
fi
if ( ($DO_TITLESETS || $TITLESET_MODE) && $VMGM_MENU ) || $PLAYALL; then
    if [[ $BUTTON_GRAVITY = "south" ]]; then
        BUTTON_GRAVITY="center"
        yecho "Changing thumb alignment to 'center' \
        to make room for navigation button"
    fi
fi

# do not use frame for showcase-framestyle glass
if [[ "$SC_FRAMESTYLE" = "glass" && -n "$SHOWCASE_VIDEO" ]] ; then
    unset SHOWCASE_FRAME
fi
# unset the showcase frame if the frame size is 0
(( ${SHOWCASE_FRAME_SIZE/x*} )) || unset SHOWCASE_FRAME

if $SHOWCASE; then
    THUMB_BG_CLR="none"   # mist backgrounds look a bit funny with showcase
fi
# easier to have non transparent showcase use the transparent block
if $SHOWCASE && ! $TRANSPARENT; then TRANSPARENT=:; fi
AUDIO_OPTS="-ab 224k -ar $SAMPLERATE -acodec $AUDIO_EXT"
# spumux and dvdauthor vars
$WIDE_SCRREN || [[ -n "$V_ASPECT" ]] && TITLES_VID_TAG="<video "
$WIDE_SCREEN && TITLES_VID_TAG=" $TITLES_VID_TAG widescreen=\"$WIDESCREEN\""
[[ -n "$V_ASPECT" ]] && TITLES_VID_TAG="$TITLES_VID_TAG $V_ASPECT"
[[ -n $TITLES_VID_TAG ]] && TITLES_VID_TAG="$TITLES_VID_TAG />"
START="00:00:00.0"
$PLAYALL && TITLESET_PRE="g4=0;"
$ITLESET_MODE && TITLESET_PRE="$TITLESET_PRE g2=1;"

if [[ -n $AUDIO_CHANNEL ]]; then
    # if only one -audio-channel value, then use for all videos
        for ((i=0; i<=NUM_FILES; i++)); do
            if [ ${#AUDIO_CHANNEL[@]} -eq 1 ]; then
                AUDIO_PRE[i]="audio=${AUDIO_CHANNEL[0]};"
            else
                AUDIO_PRE[i]="audio=${AUDIO_CHANNEL[i]};"
            fi
        done
    for ((i=0; i<=NUM_FILES; i++)); do # create audio tag for dvdauthor
        VOB_PRE[i]="        <pre> ${AUDIO_PRE[i]} </pre>"
    done
fi

MAIN_POST="        <post> jump cell 1; </post>"
if $MENU_FADE; then
    . todisc-fade-routine
    END_TIME=$(format_seconds $THUMBS_FADEOUT_ENDTIME)
    if [[ $PAUSE_TIME != "inf" ]]; then
        END=" end=\"$END_TIME\""
    fi
    START=$(format_seconds $THUMBS_FADEIN_STARTTIME)
    POST="<post> jump cell 1; </post>"

    # only do imagemagick operations on frames we will actually see
    FIRST_PIC=$THUMBS_FADEIN_STARTFRAME # 1st image to use IM on
    LAST_PIC=$THUMBS_FADEOUT_ENDFRAME
fi
# remember that static menus can have animated background or showcase video
if $STATIC && ! $MENU_FADE && [[ -z $BG_VIDEO && -z $SHOWCASE_VIDEO ]] ; then
    if ! $USER_LOOP; then
        VMGM_PAUSE="inf"
    else
        VMGM_PAUSE=$PAUSE_TIME
    fi
else
    VMGM_PAUSE=$PAUSE_TIME
fi
# pausing a -menu-fade gives a period of unselectable thumbs: use pause of 0
if $MENU_FADE && ! $USER_LOOP && [[ $VMGM_PAUSE != "inf" ]]; then
    VMGM_PAUSE=0
fi
# loop slideshows with fades by default, unless user passed -loop VALUE
$DO_CAROUSEL && $SLIDE_FADE && ! $USER_LOOP && VMGM_PAUSE=0
if [ "$PAUSE_TIME" = "inf" ]; then
    unset MAIN_POST
fi
###############################################################################
#     generate title_txt png, and template.png needed for all operations       #
###############################################################################

if [ -z "$BG_PIC" ]; then
    echo
    echo "Creating a black background"
    BG_PIC="$WORK_DIR/pics/template.png"
    $QUICK_MENU && template_colour="none" || template_colour=$BG_CLR
    convert  -resize $VIDSIZE! xc:$template_colour "$BG_PIC"
else
    convert -resize $VIDSIZE! "$BG_PIC" "$WORK_DIR/pics/template.png"
fi
if $MENU_FADE; then
    cp "$WORK_DIR/pics/template.png" "$WORK_DIR/pics/template.bk.png"
fi

if $MENU_FADE || $FEATHER; then
    convert -size $VIDSIZE xc:"#101010" "$WORK_DIR/black.jpg"
    convert -depth 8 -size $VIDSIZE xc:"#101010" "$WORK_DIR/black.ppm"
fi
# now that we have a background we can do the polaroid stack if called for
if $SINGLE_SLIDESHOW && ! $DO_CAROUSEL && ! $MK_CAROUSEL_MODE; then
    echo -e "\nMaking a 'polaroid stack' of your images for the main menu"
    mk_polaroid_stack "${MIX_IN[@]}" &
    polaroid_pid=$!
    while ps -p $polaroid_pid >/dev/null; do
        sleep .5
        spin $SPINNER
    done
    echo

    # FFMPEG_OPTS="-b 7000k  -maxrate 8000k -bufsize 224KiB -aspect 4:3"
   #MENU_N=$(bc_math "$FRAME_RATE * ${MENU_LEN[MENU_NUM-1]}" int)
    #ffmpeg -f image2 -loop_input -t $MENU_LEN -i "$WORK_DIR/image_stack.png" \
    #-an -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
    #-f mpeg2video -y "$WORK_DIR/intro.m2v"
fi
# values to use for the blur mask
DIMY=$(cut -f1 -dx <<< $THUMB_SIZE)
DIMX=$(cut -f2 -dx <<< $THUMB_SIZE)
DIMY1=$((DIMY / 20))
DIMX1=$((DIMX / 20))
DIMY2=$((DIMY - DIMY1))
DIMX2=$((DIMX - DIMY1))
DIMY3=$(($DIMY2 / 2))
DIMX3=$(($DIMX2 / 2))
DIMY4=$((DIMY / 2))
DIMX4=$((DIMX / 2))
DIMY5=$((DIMY / 3))
DIMX5=$((DIMX4 / 3))
THUMB_BLUR_CMD=(convert - -blur 0x$THUMB_BLUR -channel RGBA +matte miff:-)
SC_BLUR_CMD=(convert - -blur 0x$SC_BLUR -channel RGBA +matte miff:-)
if $THUMBS_3D && $SHOWCASE && \
    [[ $THUMB_SHAPE == "normal" || $SHOWCASE_SHAPE == "normal" ]]; then
    MASK_DIM="0,0 $DIMY,$DIMX"
    THUMB_BLUR_CMD=(convert - miff:-)
    SC_BLUR_CMD=(convert - miff:-)
else
    MASK_DIM="$DIMY1,$DIMY1 $DIMY2,$DIMX2"
fi

if [[ -n "$THUMB_SHAPE" ]] && $USE_FEATHER_MASK; then
    # make a mask for the mist if called for
    convert -size $THUMB_SIZE xc:none -fill  "$THUMB_BG_CLR" -stroke none \
    -draw "rectangle $DIMY1,$DIMY1 $DIMY2,$DIMX2" "$WORK_DIR/feather_orig.png"
    convert "$WORK_DIR/feather_orig.png" -channel RGBA \
    -blur 0x60 "$WORK_DIR/feather_mask2.png"
fi
if [[ -z "$TITLES_CLR" ]]; then
    if $USE_FEATHER_MASK && ! $SHOWCASE &&
     [[ $THUMB_BG_CLR != "none" && $THUMB_SHAPE != "normal" ]] ; then
        TITLES_CLR="#101010" # dark font for misted backgrounds
    else
        TITLES_CLR="#C6C6C6"
    fi
fi
# set submenu font colours to defaults if not passed in
[[ -z $CHAPTER_STROKE ]] && CHAPTER_STROKE="$SUBMENU_STROKE"
[[ -z $CHAPTER_CLR ]] && CHAPTER_CLR="$TITLES_CLR"

# Print and execute the thumb-shape mask command
if $DO_MENU; then
    if [[ -n $THUMB_SHAPE ]]; then
        make_mask $THUMB_SHAPE thumb
        THUMB_MASK="$MASK"
    fi
    if [[ -n $SHOWCASE_SHAPE ]]; then
        MASK="$WORK_DIR/${SHOWCASE_SHAPE}_mask.png"
        make_mask $SHOWCASE_SHAPE showcase
        convert "$MASK" -resize ${SHOWCASE_SIZE}! "$MASK"
        SHOWCASE_MASK="$MASK"
    fi
    yecho "Creating a menu title image"
    echo
    if [[ -z $TITLE_STROKE ]]; then
        if [[ -z "$BG_PIC" && -z "$BG_VIDEO" ]]; then
            TITLE_STROKE=none
        else
            TITLE_STROKE=gray
        fi
    fi
    [[ -z $TITLES_STROKE ]] && TITLES_STROKE=none

    # make a title image
    #! [[ -z ${STR// /} || -z $STR ]] && TRIM_CMD="-trim +repage -blur 0x0.4 "
    # allow removal of contrasting 'undercolour' with 'title-stroke none'
    # FIXME this is NOT IM syntax and it would be less confusing to adjust it
    [[ $TITLE_STROKE = 'none' ]] && undercolour='none' || undercolour='#101010'
    TRIM_CMD="-trim +repage -blur 0x0.3"
    TITLE_CMD=(convert  -size 620x100 xc:none -font "$MENU_FONT" -pointsize \
    $MENU_FONTSIZE -fill $undercolour -stroke $undercolour -gravity center \
    -annotate +0+0 "$MENU_TITLE" -fill "$TITLE_CLR" \
    -stroke "$TITLE_STROKE" -strokewidth 1 -annotate +1+1 "$MENU_TITLE")
    TITLE_CMD0=(composite -blend 0x${TITLE_OPACITY}  null: - -matte)
    TITLE_CMD1=(convert - $TRIM_CMD  "$WORK_DIR/title_txt.png")

    if [[ -n $TITLE_OPACITY ]]; then
        "${TITLE_CMD[@]}" miff:- | "${TITLE_CMD0[@]}" miff:- |
        "${TITLE_CMD1[@]}" >> "$LOG_FILE" 2>&1
    else
        "${TITLE_CMD[@]}" miff:- | "${TITLE_CMD1[@]}" >> "$LOG_FILE" 2>&1
    fi

    # make thumb titles
    if ! $SINGLE_SLIDESHOW; then
        for ((i=0; i<=NUM_FILES; i++)); do
            spin "Working on video title $((i+1)) "
            # if user needs -undercolor, make sure it contrasts the text colour
            THUMB_TITLE_CMD=(convert -size 620x300 xc:none -gravity $JUSTIFY \
            -font "$TITLES_FONT" -pointsize $TITLES_FONTSIZE \
            -fill $CONTRAST_CLR  -stroke $TITLES_STROKE \
            -annotate +0+0 "${TITLES[i]}" \
            -fill $TITLES_CLR  -stroke none \
            -annotate +1+1 "${TITLES[i]}")
            FADE_CMD=(composite -blend 0x${TITLES_OPACITY}  null: - -matte)
            if [[ $BUTTON_STYLE = "text" ]]; then
                TRIM_CMD=(convert - -trim "$WORK_DIR/thumb_title${i}.png")
            else
                TRIM_CMD=(convert - -trim +repage $TEXT_BORDER \
                "$WORK_DIR/thumb_title${i}.png")
            fi
            # make thumb title, only repage and border if not 'text button'
            if [[ -n $TITLES_OPACITY ]]; then
                "${THUMB_TITLE_CMD[@]}" miff:- | "${FADE_CMD[@]}" miff:- |
                "${TRIM_CMD[@]}"
            else
                "${THUMB_TITLE_CMD[@]}" miff:- | "${TRIM_CMD[@]}"
            fi
            # now get offset before repaging, for the spumux button crop later
            if [[ $BUTTON_STYLE = "text" ]]; then
                titles_offset[i]=$(identify -format %O \
                "$WORK_DIR/thumb_title${i}.png")
                titles_dim[i]=$(identify -format %wx%h \
                "$WORK_DIR/thumb_title${i}.png")
                convert "$WORK_DIR/thumb_title${i}.png" +repage \
                "$WORK_DIR/thumb_title${i}.png"
            fi

            # make spumux buttons now if 'text' button style
            if [[ $BUTTON_STYLE = "text" ]]; then
                for btn in ${HLIGHT_CLR/\#} ${SELECT_CLR/\#}; do
                    btncmd=(convert +antialias -background none \
                    -fill none -size 620x300 xc:none -font "$TITLES_FONT" \
                    -pointsize $TITLES_FONTSIZE -gravity $JUSTIFY \
                    -fill "#${btn}" -stroke none \
                    -annotate +1+1 "${TITLES[i]}" \
                    "$WORK_DIR/thumb_title${i}-${btn}.png")
                    "${btncmd[@]}"
                done
                # crop the button to the same size as the thumb_title*.png
                for clr in ${HLIGHT_CLR/\#} ${SELECT_CLR/\#}; do
                    btn="$WORK_DIR/thumb_title${i}-${clr}.png"
                    convert "$btn" +antialias \
                    -crop ${titles_dim[i]}${titles_offset[i]} +repage "$btn"
                done
                # rename textmenu buttons, - they don't need further processing
                if $SHOWCASE; then
                    mv "$WORK_DIR/thumb_title${i}-${HLIGHT_CLR/\#}.png" \
                    "$WORK_DIR/$(printf %06d%s%s ${i} -highlight .png)"
                    mv "$WORK_DIR/thumb_title${i}-${SELECT_CLR/\#}.png" \
                    "$WORK_DIR/$(printf %06d%s%s ${i} -select .png)"
                fi
            fi
            # find out dimension of the thumb title png
            TT_DIM=( ${TT_DIM[@]} $(get_image_dim \
                "$WORK_DIR/thumb_title${i}.png") )
            if ! $SHOWCASE && (( ${TT_DIM[i]/x*} > ${THUMB_SIZE/x*} )); then
                usage_error "The title \"${TITLES[i]}\" is too long to fit
                at your fontsize.  Use a smaller font with -titles-fontsize"
            fi
        done
    fi

    if $SHOWCASE; then
        for ((i=0; i<=NUM_FILES; i++)); do
            unset ts_dim j
            # get widest png in each colum for use later for alignment use
            if ((i < SPLIT)); then
                val=${TT_DIM[i]/x*}
                [ -z "$WIDEST_TITLE" ] || ((val > WIDEST_TITLE)) \
                  && WIDEST_TITLE=$val
            else
                val2=${TT_DIM[i]/x*}
                [ -z "$WIDEST_TITLE2" ] || ((val2 > WIDEST_TITLE2)) \
                  && WIDEST_TITLE2=$val2
            fi
            # get just X demension to help determine final title pos below
            tt_dim=${TT_DIM[i]/x*}
            # thumb pos + 1/2 (X dim) of thumbsize - 1/2 (X dim) of title size
            if [ "$SC_TITLE_ALIGN" = "center" ]; then
                f=$(( ${THUMB_SIZE/x*} / 2 ))
                j=$(( (f + ${SC_THUMB_X_ARRAY[i]}) - (tt_dim / 2) ))
                k=( ${k[@]} "$j" )
                l=$((j + tt_dim))
                if [ $j -lt 48 ]; then
                    off_left=$j
                    titlesafe_error $off_left
                elif [ $l -gt 672 ]; then
                    off_right=$((720 - l))
                    titlesafe_error $off_right
                fi
            fi
        done
        if $TEXTMENU; then
            # text-rect is OK with a small space between titles for spumux
            [[ $BUTTON_STYLE = "text-rect" ]] && \
              SPACER=${SPACER:-"10"} || SPACER=${SPACER:-"15"}
            # get an array of title Y positions
            offsets1=$(for ((c=0; c<NUM_FILES; c++)); do
            ((c < (LEFT_MAX-1))) && echo $((${TT_DIM[c]#*x} + SPACER)); done)
            if [[ $NUM_FILES -ge $SPLIT ]]; then
                offsets2=$(for ((d=0; d<=NUM_FILES; d++)); do
                ((d >= LEFT_MAX)) && echo $((${TT_DIM[d]#*x} + SPACER)); done)
                [[ $offsets2 ]] && offsets2="$TEXT_YSTART $offsets2"
                tt_ygeos_col2=$(running_total <<< $offsets2)
            fi
            offsets1="$TEXT_YSTART $offsets1"
            tt_ygeos_col1=$(running_total <<< $offsets1)
            tt_ygeos="$tt_ygeos_col1 $tt_ygeos_col2"
            unset SC_TITLES_Y_ARRAY
            SC_TITLES_Y_ARRAY=( $tt_ygeos_col1 $tt_ygeos_col2 )
            # get y position of the last title in 1st column (tt_ygeos_col1)
            endtitle_col1=$(wc -w <<< "$tt_ygeos_col1")
            endtitle_col1_ygeo=${SC_TITLES_Y_ARRAY[endtitle_col1-1]/*x}
            # add y dimension of the last title size to the above y position
            SW_YCORNER=$((${TT_DIM[endtitle_col1-1]/*x} + $endtitle_col1_ygeo))
            avail_space1=$(( ( ${VIDSIZE/*x} - SAFE_AREA ) - $SW_YCORNER ))
            # if there are 2 columns, get same data for column 2
            if [[ -n $tt_ygeos_col2 ]]; then
                endtitle_col2=$NUM_FILES
                endtitle_col2_ygeo=${SC_TITLES_Y_ARRAY[endtitle_col2]/*x}
                endtitle_col2_xgeo=${SC_TITLES_Y_ARRAY[endtitle_col2]/x*}
                SE_YCORNER=$((${TT_DIM[endtitle_col2]/*x}+$endtitle_col2_ygeo))
                avail_space2=$(( ( ${VIDSIZE/*x} - SAFE_AREA ) - $SE_YCORNER ))
            fi
            # available space is lowest value of 2 *space* vars ( if 2 columns)
            if [[ -n $tt_ygeos_col2 ]] && ((SE_YCORNER > SW_YCORNER)); then
                avail_space=$avail_space2
            else
                avail_space=$avail_space1
            fi
            # get the height of each column for -align centre
            if [[ $BUTTON_GRAVITY = "center" \
              || $BUTTON_GRAVITY = "east" || $BUTTON_GRAVITY = "west" ]]; then
                WEST_YSPACE=$(( SW_YCORNER - TEXT_YSTART))
                EAST_YSPACE=$((SE_YCORNER - TEXT_YSTART))
                ((WEST_YSPACE > EAST_YSPACE)) && YSPACE=$WEST_YSPACE \
                  || YSPACE=$EAST_YSPACE
                CANVAS=$(( ${VIDSIZE/*x} - (SAFE_AREA * 2) ))
                NEW_TEXT_YSTART=$(( ((CANVAS - YSPACE) / 2) + SAFE_AREA ))
                TEXT_YSTART_OFFSET=$((NEW_TEXT_YSTART - TEXT_YSTART))
            fi
            # add available space to each title position for south alignment
            if [[ $BUTTON_GRAVITY = *south* ]] && ((avail_space > 0)); then
                for ((d=0; d<=NUM_FILES; d++)); do
                    SC_TITLES_Y_ARRAY[d]=$(( $avail_space + \
                      ${SC_TITLES_Y_ARRAY[d]} ))
                done
            elif  [[ $BUTTON_GRAVITY = "center" \
              || $BUTTON_GRAVITY = "east" || $BUTTON_GRAVITY = "west" ]]; then
                for ((d=0; d<=NUM_FILES; d++)); do
                    SC_TITLES_Y_ARRAY[d]=$(($TEXT_YSTART_OFFSET + \
                      ${SC_TITLES_Y_ARRAY[d]} ))
                done
            fi
                # justify titles to the right on the east side of the menu
                ((NUM_FILES >= SPLIT-1)) && WIDE_TITLE=$WIDEST_TITLE2 \
                  || WIDE_TITLE=$WIDEST_TITLE
                for ((d=0; d<=NUM_FILES; d++)); do
                    ([[ "$BUTTON_GRAVITY" = *east* ]] \
                      || [[ -n $tt_ygeos_col2 ]]) && \
                        east_offset=$(( ( ${VIDSIZE/x*} - SAFE_AREA ) - \
                        ${TT_DIM[d]/x*} ))
                    if (($NUM_FILES < SPLIT)); then
                        SC_TITLES_X_ARRAY[d]=$SAFE_AREA
                        [[ "$BUTTON_GRAVITY" = *east* ]] && \
                          SC_TITLES_X_ARRAY[d]=$east_offset
                    else
                        if ((d >= LEFT_MAX)); then
                            SC_TITLES_X_ARRAY[d]=$east_offset
                        else
                            SC_TITLES_X_ARRAY[d]=$SAFE_AREA
                        fi
                    fi
                done
            unset MAX_VAL val max_key
        fi
        # make SHOWCASE_PAGE arrayS for thumbs and THUMBTITLES_ARRAY for titles
        # use preset values unless doing centre align for titles
        for ((i=0; i<=NUM_FILES; i++)); do
            if [ "$SC_TITLE_ALIGN" != "center" ]; then
                SC_TITLES_ARR[i]=+${SC_TITLES_X_ARRAY[i]}+${SC_TITLES_Y_ARRAY[i]}
            else
                SC_TITLES_ARR[i]=+${k[i]}+${SC_TITLES_Y_ARRAY[i]}
            fi

            SHOWCASE_THUMB_PAGES[i]="-page ${SCTHUMB_PAGES_ARRAY[i]}"
            THUMBTITLES_ARRAY[i]="-page ${SC_TITLES_ARR[i]}"
        done
    fi
fi

# make a button for playall and one for jumping to the vmgm menu, if called for
# or make a 'play' button if doing a montage slideshow menu
pa_ind=$((NUM_FILES+1))
if { $PLAYALL && $DO_MENU ; } || $SINGLE_SLIDESHOW; then
    if { $TITLESET_MODE && $VMGM_MENU ; } && ! $VMGM_ONLY; then
        $SHOWCASE && PLAYALL_BTN_yOFFSET=50 || PLAYALL_BTN_yOFFSET=80
        PLAYALL_BTN_xOFFSET=50
    else
        PLAYALL_BTN_xOFFSET=50 && PLAYALL_BTN_yOFFSET=55
    fi
    PLAYALL_BTN_OFFSETS="+$PLAYALL_BTN_xOFFSET+$PLAYALL_BTN_yOFFSET"
    mk_play_button  "#C6C6C6" '#101010' default  "$WORK_DIR/Playall.png"
    ADD_PLAYALL_BTN=("$WORK_DIR/Playall.png" -gravity SouthEast -geometry \
      "$PLAYALL_BTN_OFFSETS" -composite)
    # make the button for spumux too
    mk_play_button  "$HLIGHT_CLR" "$HLIGHT_CLR" spu \
     "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png"
    mogrify -channel A -threshold 50% \
     "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png"
    mk_play_button   "$SELECT_CLR" "$SELECT_CLR" spu \
     "$WORK_DIR/Playall_${SELECT_CLR/\#}.png"
    mogrify -channel A -threshold 50% \
     "$WORK_DIR/Playall_${SELECT_CLR/\#}.png"
    # coordinates for spumux
    X0=$(( ${VIDSIZE/x*} - PLAYALL_BTN_xOFFSET - play_btn_width))
    Y0=$((${VIDSIZE/*x} - PLAYALL_BTN_yOFFSET - play_btn_height))
    X1=$((X0 + play_btn_width))
    Y1=$((Y0 + play_btn_height))
    # spumux needs the coordinates to be divisible by 2
    ((X0%2 && X0--));  ((Y0%2 && Y0--))
    ((X1%2 && X1--));  ((Y1%2 && Y1--))
    if $SHOWCASE; then
        if $SINGLE_SLIDESHOW; then
            :
        else
            pa_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\")
            btn_geos[pa_ind]=${pa_geos[@]}
        fi
    fi
    if ! $SHOWCASE && $SINGLE_SLIDESHOW; then
        ss_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\")
       btn_geos[0]=${ss_geos[@]}
    fi
fi
# make back button for submenus
if $SUB_MENU; then
    mk_return_button "$HLIGHT_CLR" "$HLIGHT_CLR" spu \
    "$WORK_DIR/sm_back_${HLIGHT_CLR/\#}.png"
    mk_return_button  "$SELECT_CLR" "$SELECT_CLR" spu \
     "$WORK_DIR/sm_back_${SELECT_CLR/\#}.png"
    mk_return_button "#C6C6C6" '#101010' default "$WORK_DIR/sm_back.png"
    SM_BK_PNG="$WORK_DIR/sm_back.png"
fi
if $TITLESET_MODE && $VMGM_MENU && ! $VMGM_ONLY; then
    RTN_BTN_yOFFSET=50; RTN_BTN_xOFFSET=50
    RTN_BTN_OFFSETS="+$RTN_BTN_xOFFSET+$RTN_BTN_yOFFSET"
    # put return button on left side for showcase, right side if not showcase
    if $SHOWCASE; then
        RTN_BTN_GRAVITY=SouthWest
        ind=$((NUM_FILES+2))
    else
        RTN_BTN_GRAVITY=SouthEast
    fi
    mk_return_button "#C6C6C6" '#101010' default "$WORK_DIR/Main.png"
    ADD_RTN_BTN=("$WORK_DIR/Main.png" -gravity $RTN_BTN_GRAVITY \
    -geometry "$RTN_BTN_OFFSETS" -composite)
    # make the image for spumux while we at add it
    mk_return_button "$HLIGHT_CLR" "$HLIGHT_CLR" spu \
     "$WORK_DIR/Main_${HLIGHT_CLR/\#}.png"
    mk_return_button  "$SELECT_CLR" "$SELECT_CLR" spu \
     "$WORK_DIR/Main_${SELECT_CLR/\#}.png"
    # coordinates for spumux
    X0=$RTN_BTN_xOFFSET
    if ! $SHOWCASE && $SINGLE_SLIDESHOW; then
        X0=$((${VIDSIZE/x*} - $RTN_BTN_xOFFSET - rtn_btn_width))
    fi
    Y0=$((${VIDSIZE/*x} - RTN_BTN_yOFFSET - rtn_btn_height))
    X1=$((X0 + rtn_btn_width))
    Y1=$((Y0 + rtn_btn_height))
    # spumux needs the coordinates to be divisible by 2
    ((X0%2 && X0--)); ((Y0%2 && Y0--))
    ((X1%2 && X1++)); ((Y1%2 && Y1++))
    # single slideshow has hidden button - no spumux geometries needed
    if $SHOWCASE; then
        if $SINGLE_SLIDESHOW; then
            :
        else # else pass on button geometries for making spumux xml
            rtn_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\")
            btn_geos[ind]=${rtn_geos[@]}
        fi
    fi
    if ! $SHOWCASE && $SINGLE_SLIDESHOW; then
        if $TITLESET_MODE && $VMGM_MENU; then
            rtn_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\")
            btn_geos[1]=${rtn_geos[@]}
        fi
    fi
fi

if [[ -n $MENU_TITLE ]] && $DO_MENU; then
    TITLE_TEXT_DIM=$(get_image_dim "$WORK_DIR/title_txt.png")
    TITLE_TEXT_XDIM=${TITLE_TEXT_DIM/x*}
    TITLE_TEXT_YDIM=${TITLE_TEXT_DIM/*x}
fi
if $MIST; then
    echo
    echo "Making a white or colored png for the misted title background"
    echo
    # make a white/coloured png for misted background effect, only for user bg
    # add 10 pixels to width and height compared to title text png
    y=$((TITLE_TEXT_YDIM + 40))
    x=$((TITLE_TEXT_XDIM + 40))
    newX=$((TITLE_TEXT_XDIM + 30))
    newY=$((TITLE_TEXT_YDIM + 30))
    DIM=${x}x${y}
    convert -size $DIM xc:none -fill $MIST_COLOUR -stroke none \
    -draw "rectangle 10,10 $newX,$newY" "$WORK_DIR/white_orig.png"
    convert $WORK_DIR/white_orig.png -channel RGBA -blur 0x4 \
      "$WORK_DIR/white.png"
    unset X Y x y
fi
# offsets for placing title and mist for Y dimension
# place menu title lower if not text mist and -title-geo is not supplied
if $MIST; then
    if [[ $TITLE_GRAVITY = *south* || $TITLE_GRAVITY = *north* ]]; then
        title_yoffset=${title_yoffset:-"+65"}
        mist_yoffset="$(( ${title_yoffset#*[-+]} - 20))"
    else
        title_yoffset=${title_yoffset:-"+0"}
        mist_yoffset="$(( ${title_yoffset#*[-+]} - 0))"
    fi
else
    title_yoffset=${title_yoffset:-"+50"}
fi
[[ ${mist_yoffset:0:1} != [+-] ]] && mist_yoffset=+${mist_yoffset}
# offsets placing title and mist for X dimension
if $MIST; then
    mist_dim=$(get_image_dim "$WORK_DIR/white.png" )
    mist_xdim=${mist_dim/x*}
    mist_xdim_offset=$(( (mist_xdim - TITLE_TEXT_XDIM) / 2 ))
    if [[ $TITLE_GRAVITY = *st* ]]; then
        title_xoffset=${title_xoffset:-"+50"}
        mist_xoffset="$(bc_math "${title_xoffset#*[-+]} \
          - $mist_xdim_offset" int)"
        [[ ${mist_xoffset:0:1} != [+-] ]] && mist_xoffset=+${mist_xoffset}
    else
        title_xoffset=${title_xoffset:-"+0"}
        mist_xoffset=$title_xoffset
    fi
else
        title_xoffset=${title_xoffset:-"+0"}
fi
###############################################################################
#      generate a basic preview of the main menu                              #
###############################################################################
# generate images for montage and title and resize them
if [[ -n "$BG_VIDEO" ]] && ! $QUICKMENU_IS_BACKGROUND; then
    echo
    echo "Getting background video images from $BG_VIDEO"
    FFMPEG_CMD=(ffmpeg -ss $BG_SEEK -i "$BG_VIDEO" -s $VIDSIZE -vframes 1 \
    -vcodec png -an  -f rawvideo -y "$WORK_DIR/pics/template.png")
    echo -e "\nRunning: "${FFMPEG_CMD[@]}"\n" | fold -bs >> "$LOG_FILE"
    SED_VAR="frame="
    if ! "${FFMPEG_CMD[@]}" 2>&1 |strings  >> "$LOG_FILE";then
        runtime_error "Problem creating images from the video."
    fi
fi
if $SHOWCASE && ($SC_THUMB || $QUICK_MENU); then
    if [[ $SC_TITLE_ALIGN = "east" ]] && ! $TEXTMENU; then
        TS="+ ${THUMB_SIZE/x*}"
    else
        TS=0
    fi
    if (( (WIDEST_TITLE + SAFE_AREA + TS + \
      ${SHOWCASE_SIZE/x*}) > ( ${VIDSIZE/x*} - SAFE_AREA) )); then
            SHOWCASE_SIZE=$SM_SHOWCASE_SIZE
    fi
    if $TEXTMENU && [[ -n $tt_ygeos_col2 ]]; then
        SHOWCASE_SIZE=$SM_SHOWCASE_SIZE
    fi

    if $SHOWCASE_3D && [[ -n $SHOWCASE_SHAPE ]]; then
        CURVE_VARS="5 3 5 1 1"
        unset SC_RAISE # 3D shaped thumbs have no -raise - use command below
        . todisc-fade-routine
        sc_3d_cmd=(convert - -write mpr:1img -fx A  +matte \
        -blur 0x$( LC_ALL="C" bash -c "printf  "%.2f" \
        $(bc_math "6.9 + .${CURVE_ARRAY[i]/.}")" ) -shade \
        $(bc_math "115 + ${CURVE_ARRAY[i]}" int)x30 \
        -normalize mpr:1img \
        -compose Overlay -composite mpr:1img -matte \
        -compose Dst_In -composite)
    else
        sc_3d_cmd=(convert - $SC_RAISE)
    fi
    if [[ -n "$SHOWCASE_VIDEO" ]]; then
        echo "Getting video images from $SHOWCASE_VIDEO"
        if [[ "$SC_FRAMESTYLE" = "glass" ]]; then
            # some vars for get_framed_pics()
            D=2
            OUTDIR="$WORK_DIR/showcase"
            OUT="$WORK_DIR/showcase_img.png"
            VOUT="png:z=7"; FRAMES=30
            FRAME_SIZE=$SHOWCASE_SIZE
            MPLAYER_SEEK_VAL=$SHOWCASE_SEEK_VAL
            $SWITCHED && MPLAYER_SEEK_VAL=${SEEK_VAL[MENU_NUM-1]}
            echo "Using mplayer to get framed images from the showcase video"
            get_framed_pics "$SHOWCASE_VIDEO" >> "$LOG_FILE" 2>&1
            largest_png=$(du -s "$WORK_DIR"/000000*.png|sort -r |
                                awk 'NR>1{exit};1 {print $2}')
            mv -v "$largest_png" "$OUT"
            rm -f "$WORK_DIR"/00000*.png
            convert "$WORK_DIR/showcase_img.png" \
            -background none $ROTATE $WAVE miff:-|
            convert - -resize $SHOWCASE_SIZE! "$WORK_DIR/showcase_img.png"
        elif [ "$SC_FRAMESTYLE" = "none" ]; then
            if $SWITCHED; then
                FFMPEG_SEEK_VAL=${SEEK_VAL[MENU_NUM-1]}
            else
                FFMPEG_SEEK_VAL=$SHOWCASE_SEEK_VAL
            fi

            FFMPEG_CMD=(ffmpeg -ss $FFMPEG_SEEK_VAL -i "$SHOWCASE_VIDEO" \
            -s $SHOWCASE_SIZE  -vframes 1 -vcodec png -an -f rawvideo -y \
            "$WORK_DIR/showcase_img.png")
            echo -e "\nRunning: "${FFMPEG_CMD[@]}"\n" | fold -bs \
              |tee -a "$LOG_FILE"
            SED_VAR="frame="
            if ! "${FFMPEG_CMD[@]}" 2>&1 | strings >> "$LOG_FILE";then
                runtime_error "Problem creating images from the video."
            fi
            # SHOWCASE_FRAME includes size and colour, it is empty if size is 0
            if [[ -n $SHOWCASE_SHAPE ]]; then
                composite -compose CopyOpacity $SHOWCASE_MASK +matte \
                "$WORK_DIR/showcase_img.png" miff:- |
                "${sc_3d_cmd[@]}" miff:- |
                convert - -background none $ROTATE $WAVE \
                -resize $SHOWCASE_SIZE! "$WORK_DIR/showcase_img.png"
            else
                convert "$WORK_DIR/showcase_img.png" $SHOWCASE_FRAME $SC_RAISE miff:- |
                convert -background none $ROTATE $WAVE - miff:-|
                convert -size $SHOWCASE_SIZE - -resize $SHOWCASE_SIZE! \
                 "$WORK_DIR/showcase_img.png"
            fi
        fi
    elif [[ -n "$SHOWCASE_IMG" ]]; then
        
        if [[ -n $SHOWCASE_SHAPE ]]; then # apply mask and no -raise 
            SHAPE_CMD=(composite -compose CopyOpacity $SHOWCASE_MASK +matte \
            "$SHOWCASE_IMG")
        else
            SHAPE_CMD=(convert -size  $SHOWCASE_SIZE "$SHOWCASE_IMG" \
            -resize $SHOWCASE_SIZE! $SHOWCASE_FRAME $SC_RAISE)
        fi
        "${SHAPE_CMD[@]}" miff:- |
        "${sc_3d_cmd[@]}" miff:- |
        convert - -background none -bordercolor Transparent -border 8x8 \
        $ROTATE $WAVE miff:- | convert -size $SHOWCASE_SIZE - -trim +repage \
        -resize $SHOWCASE_SIZE! "$WORK_DIR/showcase_img.png"
    fi
fi
# transcode makes it harder to switch between PNG and JPEG for output
if [ $IMG_FMT = "jpg" ]; then
    EXPORT="-y jpg,null"
elif [ $IMG_FMT = "png" ]; then
    EXPORT="-y im -F png -w 04"
    QUALITY="-quality 01"
fi

# create the preview images
if ! $TEXTMENU && ! $SINGLE_SLIDESHOW && $DO_MENU; then
    for ((i=0; i<=NUM_FILES; i++)) ; do
        # don't make titles if all input files are images
        # pass -f image2 to ffmpeg if its an image (not always needed but ...)
        [[ ${file_is_image[i]} = "yes" ]] && fmt="-f image2" || fmt=""
        SV=${SEEK_VAL[i]}; CURFILE="${IN_FILES[i]##*/}"
        spin "[$((i + 1)) of ${#FILES[@]}] Seeking to $SV seconds in $CURFILE"

        FFMPEG_CMD=(ffmpeg $fmt -ss ${SEEK_VAL[i]} -i "${IN_FILES[i]}" -an \
        -vframes 1 -s $THUMB_SIZE $WORK_DIR/pics/$i/%06d.$IMG_FMT)
        CMD=( "${FFMPEG_CMD[@]}" )
        SED_VAR="frame="
        ! [[ "$SC_FRAMESTYLE" = "glass" ]] \
        && echo -e "\nRunning: "${CMD[@]}"\n" | fold -bs >> "$LOG_FILE"
        # some vars for get_framed_pics()
        VOUT="png:z=7"; FRAMES=30
        FRAME_SIZE=$THUMB_SIZE
        D=2

        if [ "$SC_FRAMESTYLE" = "glass" ]; then
            MPLAYER_SEEK_VAL=${SEEK_VAL[i]}
            get_framed_pics "${IN_FILES[i]}"  >> "$LOG_FILE" 2>&1
            largest_png=$(du -s $WORK_DIR/000*[0-9].png | sort -r |
                                        awk 'NR>1{exit};1 {print $2}')
            mv -f $largest_png $WORK_DIR/pics/$i/$(printf "%06d%s" 0 .$IMG_FMT)
            rm -f "$WORK_DIR"/000*[0-9].png
        elif [ "$SC_FRAMESTYLE" = "none" ]; then
            if ! "${FFMPEG_CMD[@]}" 2>&1 |strings >> "$LOG_FILE";then
                runtime_error "Problem creating images from the video."
            fi
        fi

        wait
        unset NAVSEEK_CMD rectangle run_transcode FFMPEG_CMD TRANSCODE_CMD
    done
    echo
fi
# overlay menu title and thumb titles on template
if $MIST; then
    # overlay white.png onto background
    echo "Overlaying the text mist on the background"
    composite -dissolve $MIST_OPACITY -gravity $TITLE_GRAVITY \
    -geometry ${mist_xoffset}${mist_yoffset} \
    "$WORK_DIR/white.png" "$WORK_DIR/pics/template.png" \
    "$WORK_DIR/pics/template.png"
fi
if $SHOWCASE && $DO_MENU; then
    for ((i=0; i<=NUM_FILES; i++)); do
        sc_thumb_title_cmd=( "${sc_thumb_title_cmd[@]}" \
        "${THUMBTITLES_ARRAY[i]}" "$WORK_DIR/thumb_title${i}.png")
    done
    echo "Running:
    convert  -size $VIDSIZE -background none "$WORK_DIR/pics/template.png"
    ${sc_thumb_title_cmd[@]} -page +210+400 "$WORK_DIR/title_txt.png" \
    -mosaic "$WORK_DIR/pics/template.png" "| format_output >> "$LOG_FILE"
    convert -size $VIDSIZE -background none "$WORK_DIR/pics/template.png" \
    ${sc_thumb_title_cmd[@]} -mosaic "$WORK_DIR/pics/template.png"
    convert "$WORK_DIR/pics/template.png" "$WORK_DIR/title_txt.png" \
    -gravity $TITLE_GRAVITY -geometry ${title_xoffset}${title_yoffset} \
    -composite -background none "$WORK_DIR/pics/template.png"
fi
if $PLAYALL || { $TITLESET_MODE && $VMGM_MENU; } || $SINGLE_SLIDESHOW ; then
    convert "$WORK_DIR/pics/template.png" -background none \
    "${ADD_PLAYALL_BTN[@]}" "${ADD_RTN_BTN[@]}" \
    "$WORK_DIR/pics/template.png"
    convert "$WORK_DIR/pics/template.png" "$WORK_DIR/pics/template.jpg"
fi

# copy the preview for -quick-menu
if $QUICK_MENU && [[ -s "$WORK_DIR/showcase_img.png" ]]; then
    cp -v "$WORK_DIR/pics/template.png" "$WORK_DIR/quick_menu_bg.png"
fi

# lets be sure of order by using a loop
for ((i=0; i<=NUM_FILES; i++)); do
    PICS=( "${PICS[@]}" \
    $(find $WORK_DIR/pics/$i/  -maxdepth 1 -name 000\*.$IMG_FMT) )
done
if ! $TEXTMENU && ! $SINGLE_SLIDESHOW && $DO_MENU; then
    # feathered and 3d thumbs get their effect here
    for ((i=0; i<${#PICS[@]}; i++)); do
        [[ -n ${ROTATE_ARRAY[@]} ]] && \
        THUMB_ROTATE="-background none -rotate ${ROTATE_ARRAY[i]}"
        if $THUMBS_3D && [ "$THUMB_SHAPE" != "normal" ]; then
        CURVE_VARS="5 3 5 1 1"
        . todisc-fade-routine
        fi
        PVIEW_CMD=(composite -compose CopyOpacity $THUMB_MASK +matte \
        "${PICS[i]}")
        PVIEW_CMD0=(convert "${PICS[i]}" $RAISE)
        PVIEW_CMD2=(convert - -write mpr:${i}img -fx A  +matte \
        -blur 0x$( LC_ALL="C" bash -c "printf  "%.2f" \
       $(bc_math "6.9 + .${CURVE_ARRAY[i]/.}")" ) -shade \
       $(bc_math "115 + ${CURVE_ARRAY[i]}" int)x30 -normalize mpr:${i}img \
       -compose Overlay -composite mpr:${i}img -matte \
       -compose Dst_In -composite)
        PVIEW_CMD3=(convert -trim +repage - "${PICS[i]}")
        if $FEATHER; then
            if $THUMBS_3D; then
                if $SHOWCASE; then
                    if [ "$THUMB_SHAPE" != "normal" ]; then
                        "${PVIEW_CMD[@]}" miff:- |
                        "${PVIEW_CMD2[@]}" miff:- |
                        "${PVIEW_CMD3[@]}"
                    else # normal thumb shape
                        "${PVIEW_CMD0[@]}" miff:- | "${PVIEW_CMD3[@]}"
                    fi
                else  # not $SHOWCASE
                    if [ "$THUMB_SHAPE" != "normal" ]; then
                        "${PVIEW_CMD[@]}" miff:- |
                        "${PVIEW_CMD2[@]}" "${PICS[i]}"
                    else # normal thumb shape
                        "${PVIEW_CMD0[@]}" miff:- | "${PVIEW_CMD3[@]}"
                    fi
                fi
            else # not 3D
                "${PVIEW_CMD[@]}" miff:- | "${PVIEW_CMD3[@]}"
            fi
        else # not FEATHER
            if $THUMBS_3D; then
                "${PVIEW_CMD0[@]}" miff:- | "${PVIEW_CMD3[@]}"
            fi
        fi
        IM_CMD=(convert -background none -bordercolor $THUMB_FRAME_CLR $THUMB_FRAME \
        $RAISE "${PICS[i]}")
        IM_CMD0=(composite -gravity center -compose DstOver \
        "$WORK_DIR/feather_mask2.png" "${PICS[i]}")
        ! $USE_FEATHER_MASK && IM_CMD0=(convert "${PICS[i]}")
        IM_CMD1=(montage "${PICS[i]}" -geometry +4+4 -compose Copy  \
        -background none)
        IM_CMD2=(convert - -resize $THUMB_SIZE!)
        IM_CMD3=(composite -gravity center -compose DstOver \
        "$WORK_DIR/feather_mask2.png" - )
        ! $USE_FEATHER_MASK && IM_CMD3=(convert -)
        IM_CMD3b=(convert - "$WORK_DIR/thumb_title${i}.png" -gravity south \
        -geometry +0+5 -compose over -composite)
        IM_CMD4=(convert "${PICS[i]}" -background none -bordercolor $THUMB_FRAME_CLR \
        $THUMB_FRAME "$WORK_DIR/thumb_title${i}.png" -gravity south \
        -geometry +0+5 -compose over -composite )
        IM_CMD5=(convert - -bordercolor none $THUMB_FRAME $THUMB_ROTATE -resize ${THUMB_SIZE}! \
        "${PICS[i]}" )
        IM_CMD6=(convert - -bordercolor $THUMB_FRAME_CLR $THUMB_FRAME \
        $THUMB_ROTATE -resize ${THUMB_SIZE}! "${PICS[i]}")
        IM_CMD7=(convert - $THUMB_ROTATE -resize ${THUMB_SIZE}! "${PICS[i]}")
        
        if $FEATHER; then
            if $SHOWCASE; then
                "${IM_CMD0[@]}" miff:- | "${IM_CMD5[@]}"
            else  # feather, but not showcase
                "${IM_CMD1[@]}" miff:- | "${IM_CMD2[@]}" miff:- |
                "${IM_CMD3[@]}" miff:- | "${IM_CMD3b[@]}" miff:- |
                "${IM_CMD5[@]}"
            fi
        else  # not feather
            if $SHOWCASE; then
                "${IM_CMD[@]}" miff:- | "${IM_CMD6[@]}"
            else # not feather and not showcase
                "${IM_CMD4[@]}" miff:- |  "${IM_CMD7[@]}"
            fi
        fi
    done
fi
##############################################################################
#                 create button layer for spumux                             #
##############################################################################

if $DO_BUTTONS; then
    echo
    echo "Creating the highlight and selection PNGs for the main menu"
    if [ "$BUTTON_STYLE" = "rect" ]; then
        MENU_BUTTON_SIZE=$THUMB_SIZE
        get_button_geo
    (
    cat  <<EOF
rectangle 2,2 $GEO
EOF
)  > "$WORK_DIR/draw_file"
    fi
    if [[ $BUTTON_STYLE = "text-rect" ]]; then
        for ((i=0; i<=NUM_FILES; i++)); do
            MENU_BUTTON_SIZE=${TT_DIM[i]}
            get_button_geo
    (
    cat <<EOF
rectangle 1,1 $GEO
EOF
    )  > "$WORK_DIR/draw_file${i}"
        done
    fi
    if [[ $BUTTON_STYLE = "line" ]]; then
        for ((i=0; i<=NUM_FILES; i++)); do
            twidth=$(convert "$WORK_DIR/thumb_title${i}.png" \
            -trim +repage -format %w info:-)
            tx1=$(( ${TT_DIM[i]/x*} - twidth))
            tx1=$((tx1 / 2))
            tx2=$(( ${TT_DIM[i]/x*} - tx1 ))
            ty=$(( ${TT_DIM[i]/*x} - 5 ))
    (
    cat <<EOF
line ${tx1},${ty} ${tx2},${ty}
EOF
    ) > "$WORK_DIR/draw_file${i}"
        done
    fi

    PNG_IS_DONE=false
    for ((t=0; t<${#TITLES[@]}; t++)); do
        unset BUTTON_CMD6b BUTTON_CMD7b
        if $FEATHER; then FRAME=0; else FRAME=3x3;fi
        [[ -n ${ROTATE_ARRAY[@]} ]] && \
         THUMB_ROTATE="-background none -rotate ${ROTATE_ARRAY[t]}"
        BUTTON_SIZE=$THUMB_SIZE
        BUTTON_CMD=(convert -size $THUMB_SIZE xc:none)
        BUTTON_CMD1=(convert +antialias -size $THUMB_SIZE xc:none \
        -mattecolor none -background none -bordercolor none \
        "$WORK_DIR/thumb_title${t}-${SELECT_CLR/\#}.png" \
        -gravity South -geometry +0+5 -compose over -composite)
        BUTTON_CMD2=(convert +antialias -size $THUMB_SIZE xc:none \
        -mattecolor none -background none -bordercolor none \
        "$WORK_DIR/thumb_title${t}-${HLIGHT_CLR/\#}.png" \
        -gravity South -geometry +0+5 -compose over -composite)
        BUTTON_CMD3=(convert - +antialias -background none \
        $THUMB_ROTATE -resize ${THUMB_SIZE}! )
        BUTTON_CMD4=(convert -size "${THUMB_SIZE}+5+5"  xc:none -fill none \
        +antialias -stroke "$SELECT_CLR" -strokewidth 4 -draw @draw_file \
        $THUMB_ROTATE -resize ${THUMB_SIZE}! \
        "$WORK_DIR/Select${t}.png")
        BUTTON_CMD5=(convert -size "${THUMB_SIZE}+5+5" xc:none -fill none \
        +antialias -stroke "$HLIGHT_CLR" -strokewidth 4 -draw @draw_file \
        $THUMB_ROTATE -resize ${THUMB_SIZE}! \
        "$WORK_DIR/Highlight${t}.png")
        BUTTON_CMD6=(convert -size ${THUMB_SIZE}+5+5 xc:none +antialias \
        -fill none -stroke "$SELECT_CLR" -strokewidth 4 -draw @draw_file \
        $THUMB_ROTATE -resize ${THUMB_SIZE}! \
        "$WORK_DIR/Select${t}.png")
        BUTTON_CMD6b=(convert +antialias \
        -size ${TT_DIM[t]} xc:none -fill none -stroke "$SELECT_CLR" \
        -strokewidth 2 -draw @draw_file${t} \
        "$WORK_DIR/$(printf %06d%s%s ${t} -select .png)")
        BUTTON_CMD7=(convert +antialias -size ${THUMB_SIZE}+5+5 \
        xc:none -fill none -stroke "$HLIGHT_CLR" -strokewidth 4 \
        -draw @draw_file $THUMB_ROTATE -resize ${THUMB_SIZE}! \
        "$WORK_DIR/Highlight${t}.png")
        BUTTON_CMD7b=(convert +antialias \
        -size ${TT_DIM[t]} xc:none -fill none -stroke "$HLIGHT_CLR" \
        -strokewidth 2 -draw @draw_file${t} \
        "$WORK_DIR/$(printf %06d%s%s ${t} -highlight .png)")

        if [[ $BUTTON_STYLE = "text" ]] && ! $SHOWCASE; then
            if $FEATHER; then
                "${BUTTON_CMD2[@]}" miff:- | "${BUTTON_CMD3[@]}" \
                "$WORK_DIR/$(printf %06d%s%s ${t} -select .png)"
                "${BUTTON_CMD2[@]}" miff:- | "${BUTTON_CMD3[@]}" \
                "$WORK_DIR/$(printf %06d%s%s ${t} -highlight .png)"
            else
                "${BUTTON_CMD2[@]}" miff:- |
                "${BUTTON_CMD3[@]}" \
                "$WORK_DIR/$(printf %06d%s%s ${t} -select .png)"
                "${BUTTON_CMD2[@]}" miff:- | "${BUTTON_CMD3[@]}" \
                "$WORK_DIR/$(printf %06d%s%s ${t} -highlight .png)"
            fi
            mogrify -channel A -threshold 50% \
            "$WORK_DIR/$(printf %06d%s%s ${t} -select .png)"
            mogrify -channel A -threshold 50% \
            "$WORK_DIR/$(printf %06d%s%s ${t} -highlight .png)"

        elif [[ $BUTTON_STYLE = "rect" ]]; then
            if  ! $PNG_IS_DONE; then
                if $SHOWCASE; then
                    "${BUTTON_CMD6[@]}"
                    "${BUTTON_CMD7[@]}"
                else
                    "${BUTTON_CMD4[@]}" #2> /dev/null
                    "${BUTTON_CMD5[@]}" #2> /dev/null
                fi
            fi
        elif [[ $BUTTON_STYLE = "text-rect" ]] \
            || { [[ $BUTTON_STYLE = "line" ]] && ! $SHOWCASE ; }; then
            # "line" style for non showcase can use same code as text-rect
            # showcase "line" style button montage is created later in one shot
            "${BUTTON_CMD6b[@]}"
            "${BUTTON_CMD7b[@]}"
            if ! $SHOWCASE; then
                # 'line' button style goes at the very bottom of the thumb
                [[ $BUTTON_STYLE = "line" ]] && butgeo=+0+0 || butgeo=+0+5

                convert -size $BUTTON_SIZE xc:none "$WORK_DIR/blank.png"
                convert +antialias $WORK_DIR/blank.png \
                "$WORK_DIR/$(printf %06d%s%s ${t} -select .png)" -gravity \
                South -geometry $butgeo -composite $THUMB_ROTATE -resize \
                ${BUTTON_SIZE}! "$WORK_DIR/$(printf %06d%s%s ${t} -select .png)"
                mogrify -channel A -threshold 50% \
                "$WORK_DIR/$(printf %06d%s%s ${t} -select .png)"
                convert +antialias $WORK_DIR/blank.png  \
                "$WORK_DIR/$(printf %06d%s%s ${t} -highlight .png)" \
                -gravity south -geometry $butgeo -composite $THUMB_ROTATE \
                -resize ${BUTTON_SIZE}! \
                "$WORK_DIR/$(printf %06d%s%s ${t} -highlight .png)"
                mogrify -channel A -threshold 50% \
                "$WORK_DIR/$(printf %06d%s%s ${t} -highlight .png)"
            fi
        fi
        # do not loop over creating same png
#        [[ -z ${ROTATE_ARRAY[@]} ]] && PNG_IS_DONE=:
    done
    if [ "$BUTTON_STYLE" = "rect" ]; then
        BUTTON_DIM=$(get_image_dim "$WORK_DIR/Highlight0.png")
        for button in Select Highlight; do
            if $SHOWCASE; then
                unset sc_spumux_cmd fake_montage_cmd
                convert -size $BUTTON_DIM xc:none -background none \
                $WORK_DIR/empty-button.png
                fake_montage=( $WORK_DIR/Highlight0.png \
                $(for ((i=0; i<NUM_FILES; i++)); do \
                echo $WORK_DIR/empty-button.png; done))
                for ((i=0; i<=NUM_FILES; i++)); do
                    fake_montage_cmd=( ${fake_montage_cmd[@]} \
                    ${SHOWCASE_THUMB_PAGES[i]} "${fake_montage[i]}")
                    sc_spumux_cmd=( ${sc_spumux_cmd[@]} \
                    ${SHOWCASE_THUMB_PAGES[i]} "$WORK_DIR/${button}${i}.png" )
                    # get button locations for spumux
                    btn_size=$(get_image_dim "$WORK_DIR/${button}${i}.png")
                    # a couple of commented references
                    #${SC_THUMB_X_ARRAY[i]}+${SC_THUMB_Y_ARRAY[i]}
                    #btn_geos[ind]="x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\""
                    X0=${SC_THUMB_X_ARRAY[i]}; X1=$((X0 + ${btn_size/x*}))
                    Y0=${SC_THUMB_Y_ARRAY[i]}; Y1=$((Y0 + ${btn_size/*x}))
                    # spumux needs the coordinates to be divisible by 2
                    ((X0%2 && X0--)); ((Y0%2 && Y0--))
                    ((X1%2 && X1++)); ((Y1%2 && Y1++))
                    button_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\")
                    btn_geos[i]=${button_geos[@]}
                    unset button_geos
                done
                convert  -size $VIDSIZE xc:none -background none \
                ${fake_montage_cmd[@]} -mosaic "$WORK_DIR/fake_montage.png"
                convert +antialias -size $VIDSIZE xc:none \
                -background none ${sc_spumux_cmd[@]} -mosaic \
                "$WORK_DIR/${button}.png"
            else
                montage -background none \
                $(for ((i=0; i<=NUM_FILES; i++)); do
                echo $WORK_DIR/${button}${i}.png;done) -tile \
                ${TILE_ARRAY[NUM_FILES]} -geometry ${THUMB_SIZE}${MTG_GEO} \
                -bordercolor none -mattecolor transparent miff:- |
                convert +antialias  -size $VIDSIZE xc:none - -gravity \
                $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} -composite \
                "$WORK_DIR/${button}.png"
                convert -size $BUTTON_DIM xc:none -background none \
                $WORK_DIR/empty-button.png
                fake_montage=( $WORK_DIR/Highlight0.png \
                $(for ((i=0; i<NUM_FILES; i++)); do \
                echo $WORK_DIR/empty-button.png; done))
                montage -background none ${fake_montage[@]} \
                -tile ${TILE_ARRAY[NUM_FILES]} -geometry ${THUMB_SIZE}${MTG_GEO} \
                -bordercolor none -mattecolor transparent miff:- | convert \
                -size $VIDSIZE xc:none - -gravity $BUTTON_GRAVITY -geometry \
                +${XGEO}+${YGEO} -composite "$WORK_DIR/fake_montage.png"
            fi
        done
    elif [[ "$BUTTON_STYLE" = *text* ]]; then
        if $SHOWCASE; then
            select_buttons=( ${select_buttons[@]} \
            $(find $WORK_DIR/ -name 00\*select.png |sort) )
            highlight_buttons=( ${highlight_buttons[@]} \
            $(find $WORK_DIR/ -name 00\*highlight.png |sort) )
            for ((i=0; i<=NUM_FILES; i++)); do
                sc_select_cmd=(${sc_select_cmd[@]} \
                ${THUMBTITLES_ARRAY[i]} "${select_buttons[i]}")
                sc_highlight_cmd=(${sc_highlight_cmd[@]} \
                ${THUMBTITLES_ARRAY[i]} "${highlight_buttons[i]}")
            done
            convert +antialias -quality 01 \
            -size $VIDSIZE xc:none -background none \
            ${sc_highlight_cmd[@]} -mosaic "$WORK_DIR/Highlight.png"
            convert +antialias -quality 01 \
            -size $VIDSIZE xc:none -background none \
            ${sc_select_cmd[@]} -mosaic "$WORK_DIR/Select.png"
        else
            select_buttons=( ${select_buttons[@]} \
            $(find $WORK_DIR/ -name 00\*select.png |sort) )
            highlight_buttons=( ${highlight_buttons[@]} \
            $(find $WORK_DIR/ -name 00\*highlight.png |sort) )
            montage -background none \
            ${select_buttons[@]} -tile ${TILE_ARRAY[NUM_FILES]} \
            -geometry ${THUMB_SIZE}${MTG_GEO} -bordercolor none \
            -mattecolor none miff:- |
            convert  +antialias -size $VIDSIZE xc:none \
            - -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} \
            -composite  "$WORK_DIR/Select.png"
            montage -background none \
            ${highlight_buttons[@]} -tile ${TILE_ARRAY[NUM_FILES]} -geometry \
            ${THUMB_SIZE}${MTG_GEO} -bordercolor none -mattecolor none miff:- |
            convert +antialias -size $VIDSIZE xc:none - \
            -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} -composite \
            "$WORK_DIR/Highlight.png"
            BUTTON_DIM=$(get_image_dim "$WORK_DIR/000000-highlight.png")
            convert -size $BUTTON_DIM xc:none -background none \
            $WORK_DIR/empty-button.png
            fake_montage=( $WORK_DIR/000000-highlight.png \
            $(for ((i=0; i<NUM_FILES; i++)); do \
            echo $WORK_DIR/empty-button.png; done))
        fi
        if $SHOWCASE; then
            if [[ $BUTTON_STYLE = *text* ]]; then
                convert +antialias -size $VIDSIZE xc:none \
                -background none ${THUMBTITLES_ARRAY[MENU_NUM-1]} \
                $WORK_DIR/$(printf "%06d%s" $((MENU_NUM-1)) -highlight.png) \
                -mosaic "$WORK_DIR/fake_montage.png"
            fi
        else
            montage -background none ${fake_montage[@]} \
            -tile ${TILE_ARRAY[NUM_FILES]} -geometry ${THUMB_SIZE}${MTG_GEO} \
            -bordercolor none -mattecolor transparent miff:- |
            convert  -size $VIDSIZE xc:none - -gravity $BUTTON_GRAVITY \
            -geometry +${XGEO}+${YGEO} -composite "$WORK_DIR/fake_montage.png"
        fi
    elif $SHOWCASE && [[ "$BUTTON_STYLE" = "line" ]]; then
        for i in ${!TITLES[@]}; do
            XPT1=$( cut -f2 -d+ <<< ${THUMBTITLES_ARRAY[i]} )
            XPT2=$(( XPT1 + ${TT_DIM[i]%%x*} ))
            YPT=$( cut -f3 -d+ <<< ${THUMBTITLES_ARRAY[i]} )
            YPT=$(( YPT + ${TT_DIM[i]##*x} ))
            # Y0,X0,Y0,Y1 is for later, for spumux button geometries
            Y0=$YPT
            X0=$XPT1
            X1=$XPT2
            # for line button just add 2 to Y geo
            Y1=$((Y0+2))
            # make sure coordinates are even
            ((X0%2 && X0--)); ((Y0%2 && Y0--))
            ((X1%2 && X1++)); ((Y1%2 && Y1++))
            button_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\") #FIXME
            btn_geos[i]=${button_geos[@]}
            unset button_geos
            echo \
            "line ${XPT1},${YPT} ${XPT2},${YPT}" >> "$WORK_DIR/spumux_drawfile"
            [[ $i -eq $((MENU_NUM-1)) ]] && echo \
            "line ${XPT1},${YPT} ${XPT2},${YPT}" >>"$WORK_DIR/fake_montage.mvg"
        done
        convert +antialias -size $VIDSIZE xc:none -fill none \
        -stroke $SELECT_CLR -strokewidth 2 -draw @spumux_drawfile \
        "$WORK_DIR/Select.png"
        convert +antialias -size $VIDSIZE xc:none -fill none \
        -stroke $HLIGHT_CLR \
        -strokewidth 2 -draw @spumux_drawfile "$WORK_DIR/Highlight.png"
        convert  -size $VIDSIZE xc:none -fill none -stroke $HLIGHT_CLR \
        -strokewidth 2 -draw @fake_montage.mvg "$WORK_DIR/fake_montage.png"
    elif  ! $SHOWCASE && [[ $BUTTON_STYLE = "line" ]]; then
        select_buttons=( ${select_buttons[@]} \
        $(find $WORK_DIR/ -name 00\*select.png |sort) )
        highlight_buttons=( ${highlight_buttons[@]} \
        $(find $WORK_DIR/ -name 00\*highlight.png |sort) )

        montage -background none ${select_buttons[@]} \
        -tile ${TILE_ARRAY[NUM_FILES]} -geometry ${THUMB_SIZE}${MTG_GEO} \
        -bordercolor none -mattecolor none miff:- |
        convert +antialias -size $VIDSIZE xc:none - \
        -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} \
        -composite "$WORK_DIR/Select.png"

        montage -background none ${highlight_buttons[@]} \
        -tile ${TILE_ARRAY[NUM_FILES]} -geometry ${THUMB_SIZE}${MTG_GEO} \
        -bordercolor none -mattecolor none miff:- |
        convert +antialias -size $VIDSIZE xc:none - \
        -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} \
        -composite "$WORK_DIR/Highlight.png"

        BUTTON_DIM=$(get_image_dim "$WORK_DIR/000000-highlight.png")
        convert -size $BUTTON_DIM xc:none -background none \
        $WORK_DIR/empty-button.png
        fake_montage=( $WORK_DIR/000000-highlight.png \
        $(for ((i=0; i<NUM_FILES; i++)); do \
        echo $WORK_DIR/empty-button.png; done))

        montage -background none ${fake_montage[@]} \
        -tile ${TILE_ARRAY[NUM_FILES]} -geometry ${THUMB_SIZE}${MTG_GEO} \
        -bordercolor none -mattecolor transparent miff:- |
        convert  -size $VIDSIZE xc:none - -gravity $BUTTON_GRAVITY \
        -geometry +${XGEO}+${YGEO} -composite "$WORK_DIR/fake_montage.png"
    fi
    if $TITLESET_MODE && ! $VMGM_ONLY && $VMGM_MENU; then
        convert +antialias -gravity $RTN_BTN_GRAVITY \
        -geometry "$RTN_BTN_OFFSETS" "$WORK_DIR/Select.png" \
        "$WORK_DIR/Main_${SELECT_CLR/\#}.png" -composite "$WORK_DIR/Select.png"

        convert +antialias -gravity $RTN_BTN_GRAVITY \
        -geometry "$RTN_BTN_OFFSETS" "$WORK_DIR/Highlight.png" \
        "$WORK_DIR/Main_${HLIGHT_CLR/\#}.png" \
        -composite "$WORK_DIR/Highlight.png"
    fi
    if $PLAYALL; then
        convert +antialias -gravity SouthEast -geometry \
        "$PLAYALL_BTN_OFFSETS" "$WORK_DIR/Select.png" \
        "$WORK_DIR/Playall_${SELECT_CLR/\#}.png" \
        -composite "$WORK_DIR/Select.png"

        convert +antialias -gravity SouthEast -geometry \
        "$PLAYALL_BTN_OFFSETS" "$WORK_DIR/Highlight.png" \
        "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png" \
        -composite "$WORK_DIR/Highlight.png"
    fi

fi
# for dvd slideshow we need just a Select.png unless grouping or MONTAGE_MENU
if $SINGLE_SLIDESHOW; then
    if $TITLESET_MODE && ! $VMGM_ONLY && $VMGM_MENU; then
        convert +antialias -size $VIDSIZE xc:none -fill none  \
        "$WORK_DIR/Main_${SELECT_CLR/\#}.png" -gravity $RTN_BTN_GRAVITY \
        -geometry "$RTN_BTN_OFFSETS" -composite "$WORK_DIR/Select.png"
        convert +antialias -size $VIDSIZE xc:none -fill none \
        "$WORK_DIR/Main_${HLIGHT_CLR/\#}.png" -gravity $RTN_BTN_GRAVITY \
        -geometry "$RTN_BTN_OFFSETS" -composite "$WORK_DIR/Highlight.png"

        convert +antialias -gravity SouthEast -geometry \
        "$PLAYALL_BTN_OFFSETS"  "$WORK_DIR/Select.png" \
        "$WORK_DIR/Playall_${SELECT_CLR/\#}.png" \
        -composite "$WORK_DIR/Select.png"

        convert +antialias -gravity SouthEast -geometry \
        "$PLAYALL_BTN_OFFSETS" "$WORK_DIR/Highlight.png" \
        "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png" \
        -composite "$WORK_DIR/Highlight.png"
    else
        convert +antialias -size $VIDSIZE xc:none -fill none  \
        "$WORK_DIR/Playall_${SELECT_CLR/\#}.png" -gravity SouthEast \
        -geometry "$PLAYALL_BTN_OFFSETS" -composite "$WORK_DIR/Select.png"
        convert +antialias -size $VIDSIZE xc:none -fill none  \
        "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png" -gravity SouthEast \
        -geometry "$PLAYALL_BTN_OFFSETS" -composite "$WORK_DIR/Highlight.png"
    fi
    OUTLINEWIDTH="\"14\"" # needed for text button
fi
# this reduces colours so spumux is happy
for button in Select Highlight; do
    num_colours=$(identify -ping -format %k "$WORK_DIR/${button}.png")
    if ((num_colours > 3)); then
        echo "$button button had $num_colours colors, reducing ..." |
        tee -a "$LOG_FILE"
        mogrify -channel A -threshold 50% "$WORK_DIR/${button}.png"
    fi
    echo
done
# make a draw files for grid preview if -grid was passed
if ((GRID)); then
    # make draw files for grid
    for ((i=20; i<=${VIDSIZE/x*}; i=i+20)); do
        ((i<=${VIDSIZE/*x})) && echo "line 0,${i} ${VIDSIZE/x*},${i}"
        echo "line ${i},0 ${i},${VIDSIZE/*x}"
    done >> "$WORK_DIR/grid1.mvg"

    # make draw files for numbered text
    for ((i=100; i<=600; i=i+100)); do
        ((i<=${VIDSIZE/*x}-40)) && echo text 0,${i} \'$i\'
        echo text ${i},20 \'$i\'
    done >> "$WORK_DIR/grid2.mvg"
fi

if $SHOWCASE && $DO_MENU; then
    if $SC_THUMB; then
        # find out where to put the showcase image/video in the X axis
        sc_size=$(get_image_dim "$WORK_DIR/showcase_img.png")
        sc_width=${sc_size/x*}
        sc_height=${sc_size/*x}
    fi
    $QUICK_MENU && \
    sc_width=${SHOWCASE_SIZE/x*} && sc_height=${SHOWCASE_SIZE/*x}
    if $SC_THUMB || $QUICK_MENU; then #&& ! $TEXTMENU; then
        if [[ "$SC_TITLE_ALIGN" = "center" ]]; then
            if [[ $WIDEST_TITLE -ge ${THUMB_SIZE/x*} ]]; then
                BUTTON_COLUMN1=$(((${THUMB_SIZE/x*} / 2) + (WIDEST_TITLE / 2)))
            else
                BUTTON_COLUMN1=${THUMB_SIZE/x*}
            fi
        elif [[ "$SC_TITLE_ALIGN" = "west" ]]; then
            if [[ $WIDEST_TITLE -ge ${THUMB_SIZE/x*} ]]; then
                BUTTON_COLUMN1=$((WIDEST_TITLE + 5))
            else
                BUTTON_COLUMN1=${THUMB_SIZE/x*}
            fi
        elif [[ "$SC_TITLE_ALIGN" = "east" ]]; then
            BUTTON_COLUMN1=$(( ${THUMB_SIZE/x*} + WIDEST_TITLE ))
        fi
        if ! $TEXTMENU; then
        sc_space=$((${VIDSIZE%x*} - \
            ${SC_THUMB_X_ARRAY[0]} - BUTTON_COLUMN1 - SAFE_AREA))
        SC_X=$(( ${SC_THUMB_X_ARRAY[0]} + BUTTON_COLUMN1 \
            + (sc_space / 2) - (sc_width / 2) ))
        else
            BUTTON_COLUMN1=$((WIDEST_TITLE + 5))
            sc_space=$((${VIDSIZE%x*} - \
                ${SC_TITLES_X_ARRAY[0]} - BUTTON_COLUMN1 - SAFE_AREA))
            SC_X=$(( ${SC_TITLES_X_ARRAY[0]} + BUTTON_COLUMN1 \
            + (sc_space / 2) - (sc_width / 2) ))
            if [[ $BUTTON_GRAVITY = *east* ]]; then
                BUTTON_COLUMN1=$WIDEST_TITLE
                sc_space=$((${VIDSIZE%x*} - (SAFE_AREA * 2) - BUTTON_COLUMN1))
                SC_X=$((SAFE_AREA + (sc_space / 2) - (sc_width / 2) ))
            fi
        fi
        # find out where to put the showcase image in the Y axis
        if ! $TEXTMENU; then
            Y1=${SC_THUMB_Y_ARRAY[0]}
            Y2=${SC_THUMB_Y_ARRAY[NUM_FILES]}
            ((NUM_FILES >= LEFT_MAX)) && Y2=${SC_THUMB_Y_ARRAY[SPLIT-1]}
            Y_SPACE=$(( (Y2 - Y1) + ${THUMB_SIZE/*x} ))
            Y_SPACE=$(( Y_SPACE - sc_height ))
            SC_Y=$(( Y_SPACE / 2))
            SC_Y=$(( ${SC_THUMB_Y_ARRAY[0]} + SC_Y ))
        else # TEXTMENU
#            ((NUM_FILES < SPLIT)) && split=$NUM_FILES || split=$((SPLIT - 1))
            # if there is a menu title, move the showcase thumb up or down
            if [[ -n $MENU_TITLE ]] && ! $USER_SC_GEO && ! $USER_TITLE_GEO; then
                [[ $TITLE_GRAVITY = "south" ]] && \
                TITLE_SPACE="- $(( (title_yoffset + TITLE_TEXT_YDIM) / 2))"
                [[ $TITLE_GRAVITY = "north" ]] && \
                TITLE_SPACE="+ $(( (title_yoffset + TITLE_TEXT_YDIM) / 2))"
            fi
            Y_SPACE=${VIDSIZE#*x}
            SC_Y=$(( (Y_SPACE / 2) - (sc_height / 2) $TITLE_SPACE ))

        fi

        ! $TEXTMENU && [[ $V_TOTAL -gt 5 ]] && \
        SC_X=$(( ( ${VIDSIZE/x*} / 2 ) - (sc_width / 2) ))
        $TEXTMENU && [[ -n $tt_ygeos_col2 ]] \
        && SC_X=$(( ( ${VIDSIZE/x*} / 2 ) - (sc_width / 2) ))
        $USER_SC_GEO && SC_X=${SHOWCASE_GEO/x*}
        $USER_SC_GEO && SC_Y=${SHOWCASE_GEO/*x}

        # make sure its divisible by 2 for ffmpeg's padding with -quick-menu
        if $QUICK_MENU; then
            SC_Y=$(( (SC_Y /2) * 2 ))
            SC_X=$(( (SC_X / 2) * 2 ))
        fi
        SC_IMG_PAGE="-page +$SC_X+$SC_Y"
        SC_IMG_CMD="$SC_IMG_PAGE "$WORK_DIR/showcase_img.png""
    fi
    if ! $SC_THUMB; then unset SC_IMG_CMD ; fi
    if [[ -n "$SHOWCASE_IMG" || -n "$SHOWCASE_VIDEO" ]]; then
        unset sc_cmd
        for ((i=0; i<=NUM_FILES; i++)); do
            sc_cmd=( ${sc_cmd[@]} ${SHOWCASE_THUMB_PAGES[i]} "${PICS[i]}")
        done
        $TEXTMENU && unset sc_cmd
        if $TRANSPARENT; then
            IM_CMD0=(convert  -size $VIDSIZE xc:none -background none \
            ${sc_cmd[@]} $SC_IMG_CMD -mosaic)
            IM_CMD1=(convert -size $VIDSIZE -background none \
            - ${sc_thumb_title_cmd[@]} -mosaic)
            IM_CMD2=(composite -size $VIDSIZE -background none \
            -gravity NorthWest  -dissolve $OPACITY - \
            "$WORK_DIR/pics/template.png" -background none)
            IM_CMD3=(convert - -background none $WORK_DIR/title_txt.png  \
            -gravity $TITLE_GRAVITY -geometry \
            ${title_xoffset}${title_yoffset} -composite "$PREVIEW_IMG" )
            echo "Running ${IM_CMD0[@]} miff:- | ${IM_CMD1[@]} miff:- |
            ${IM_CMD2[@]} miff:- | ${IM_CMD3[@]}" |format_output >> "$LOG_FILE"
            "${IM_CMD0[@]}" miff:- | "${IM_CMD1[@]}" miff:- |
            "${IM_CMD2[@]}" miff:- | "${IM_CMD3[@]}"
        else
            IM_CMD=(convert  -size $VIDSIZE "$WORK_DIR/pics/template.png" \
            -background none ${sc_cmd[@]} $SC_IMG_CMD \
            -mosaic "$PREVIEW_IMG")
            echo "Running ${IM_CMD[@]}" |format_output >> "$LOG_FILE"
            "${IM_CMD[@]}"
        fi
        unset sc_cmd IM_CMD05 IM_CMD04 IM_CMD03 IM_CMD4
    fi
elif ! $SHOWCASE && ! $SINGLE_SLIDESHOW && $DO_MENU; then # not showcase
    if $TRANSPARENT; then
        IM_CMD1=(montage ${PICS[@]} $MTG_FRM -blur 0x.3 \
        -tile ${TILE_ARRAY[NUM_FILES]} -geometry ${THUMB_SIZE}${MTG_GEO} \
        -background none -bordercolor '#444744' miff:- )
        IM_CMD2=(composite -dissolve $OPACITY \
        -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} - \
        "$WORK_DIR/pics/template.png" -background none miff:- )
        IM_CMD3=(convert - -background none "$WORK_DIR/title_txt.png"  \
        -gravity $TITLE_GRAVITY -geometry ${title_xoffset}${title_yoffset} \
        -composite "$PREVIEW_IMG")
        echo "Running ${IM_CMD1[@]} | ${IM_CMD2[@]} | ${IM_CMD3[@]}" |
        format_output >> "$LOG_FILE"
        "${IM_CMD1[@]}" | "${IM_CMD2[@]}" | "${IM_CMD3[@]}"
    else # Not transparent
        IM_CMD1=(montage ${PICS[@]} $MTG_FRM -tile ${TILE_ARRAY[NUM_FILES]} \
        -geometry ${THUMB_SIZE}${MTG_GEO}  -background none \
        -bordercolor "#444744" miff:- )
        IM_CMD2=(convert "$WORK_DIR/pics/template.png" \
        "$WORK_DIR/title_txt.png" -gravity $TITLE_GRAVITY \
        -geometry ${title_xoffset}${title_yoffset} -composite - -gravity \
        $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} -composite "$PREVIEW_IMG")
        echo "Running ${IM_CMD1[@]} | ${IM_CMD1[@]}" |
        format_output >> "$LOG_FILE"
        "${IM_CMD1[@]}" | "${IM_CMD2[@]}"
    fi
fi
# make a preview for static slideshow menu #FIXME this should use $STATIC
if $SINGLE_SLIDESHOW && ! $DO_CAROUSEL && ! $MK_CAROUSEL_MODE; then
    IM_CMD1=(composite -dissolve $OPACITY -gravity $BUTTON_GRAVITY -geometry \
    +${XGEO}+${YGEO} "$WORK_DIR/polaroid_stack.png" \
    "$WORK_DIR/pics/template.png" -background none miff:- )
    IM_CMD2=(convert - -background none "$WORK_DIR/title_txt.png" \
    -gravity $TITLE_GRAVITY -geometry ${title_xoffset}${title_yoffset} \
    -composite "${add_playbtn[@]}" "$PREVIEW_IMG" )
    echo "Running ${IM_CMD1[@]} | ${IM_CMD1[@]}" | format_output >> "$LOG_FILE"
    "${IM_CMD1[@]}" | "${IM_CMD2[@]}"
fi
# if there is quickmenu bg, cut out transparent hole for showcase image/video
if $QUICK_MENU; then
    if $QUICKMENU_IS_SHOWCASE && [[ -n "$BACKGROUND" ]]; then
        #[[ -n $SC_MATTECOLOR ]] && SC_MATTECOLOR="-mattecolor $SC_MATTECOLOR"
        # make a blank png for cutting out showcase area (cookie cutter)
        convert -size $SHOWCASE_SIZE xc:black "$WORK_DIR/showcase_blank.png"
        # make a similar framed blank to composite onto the background
        frame_cmd=(convert -size $SHOWCASE_SIZE xc:black \
        $SHOWCASE_FRAME "$WORK_DIR/showcase_frame.png")
        yecho "Running ${frame_cmd[@]}" | format_output >> "$LOG_FILE"
        "${frame_cmd[@]}" >> "$LOG_FILE"
        # composite the framed blank onto background subtracting the width \
        # of the frame (border) when calculating XxY geometry
        convert "$WORK_DIR/pics/template.png" \
        "$WORK_DIR/showcase_frame.png" -geometry \
        +$((SC_X-${SHOWCASE_FRAME_SIZE/x*}))+$((SC_Y-${SHOWCASE_FRAME_SIZE/x*})) \
        -composite "$WORK_DIR/pics/template.png"
        # add blank to a transparent image the size of the menu video
        convert -size  $VIDSIZE xc:none "$WORK_DIR/showcase_blank.png" \
       -geometry +$SC_X+$SC_Y -composite "$WORK_DIR/cookie_cutter.png"

        # cut out transparent hole in background with this 'cookie cutter'
        convert "$WORK_DIR/cookie_cutter.png" "$WORK_DIR/pics/template.png" \
        -compose Xor -composite "$WORK_DIR/quick_menu_bg.png"
    else
        cp "$WORK_DIR/pics/template.png" "$WORK_DIR/quick_menu_bg.png"
    fi
fi
$QUICK_MENU && quick_menu preview
if ! $NOASK && $MONTAGE_MENU && $DO_MENU \
 && ! $MK_CAROUSEL_MODE && ! { $VMGM_ONLY && ! $VMGM_MENU ; }; then
    DISPLAY_PREVIEW=:
else
    DISPLAY_PREVIEW=false
fi
if $DISPLAY_PREVIEW; then
    echo "Creating and displaying a preview of the main menu."
    echo "(Press 'q' or ESC in the preview window to close it.)"
fi
# make the fake montage with highlighted 1st button and display it
if $DO_MENU && ! $SINGLE_SLIDESHOW; then #FIXME ?
    composite -compose Over "$WORK_DIR/fake_montage.png" \
      "$PREVIEW_IMG" "$PREVIEW_IMG"
fi
if $DISPLAY_PREVIEW; then
    display -title "Preview: (not in aspect) - close window to continue" \
    "$PREVIEW_IMG"
    if ((GRID)); then
        convert "$PREVIEW_IMG" \
         -stroke '#FFF5B270' -strokewidth 1 -draw @grid1.mvg miff:- | convert \
         - -fill none -stroke '#FFFFFF' -strokewidth 1 -draw @grid2.mvg x:
    fi
    confirm_preview
fi
# copy the template back if using $MENU_FADE
if $MENU_FADE; then
    rm "$WORK_DIR/pics/template.png"
    cp "$WORK_DIR/pics/template.bk.png" "$WORK_DIR/pics/template.png"
fi
rm -f "${PICS[@]}"
unset PICS IM_CMD1 IM_CMD2 IM_CMD3 IM_CMD4 IM_CMD5


###############################################################################
#   get information about input videos, and some post preview preliminaries   #
###############################################################################

# if -bgvideo selected, but not -bgaudio, offer to use audio from bgvideo
# if "none" is passed for BG_AUDIO it means we are doing switched menus
# in which case we want to skip this step anyway
if ! $NOASK && ! $SWITCHED && [[ -n "$BG_VIDEO" ]]; then
    echo "Getting stats on the background video"
    BGVIDEO_STATS=$(idvid -terse -fast "$BG_VIDEO" 2>/dev/null)
    if [[ -z "$BG_AUDIO" ]]; then
        if grep -q "A_NOAUDIO=:" <<< "$BGVIDEO_STATS"; then
            :
        else
            echo "***** NOTE *****"
            echo "You selected -bgvideo but not -bgaudio"
            echo "To use the audio from "$BG_VIDEO" please type: yes"
            read bgaudio
            if [ ! -z "$bgaudio" -a "$bgaudio" = "yes" ]; then
                BG_AUDIO="$BG_VIDEO"
                echo "Using audio from "$BG_VIDEO""
            else
                echo "No audio selected, will use silence for main menu"
            fi
        fi
    fi
fi

# find out the length of the -bgaudio FILE, if there is one
if [[ -n "$BG_AUDIO" ]]; then
    yecho "Getting length of bg audio"
    $SINGLE_SLIDESHOW && end_pos="" || end_pos=${MENU_LEN[MENU_NUM-1]}
    BG_AUDIOLENGTH=$(audio_length "$BG_AUDIO")

    # make sure user isn't trying to get a longer menu than the audio allows
    if [[ $(bc <<< "${MENU_LEN[MENU_NUM-1]} \
    > $BG_AUDIOLENGTH" 2>/dev/null)  -eq 1 ]]; then
        MENU_AUDIOLEN=$BG_AUDIOLENGTH
    fi
fi
# if static menu and no background audio, ignore MENU_AUDIOLEN
$STATIC && [[ -z "$BG_AUDIO" ]] && ! $SWITCHED && unset MENU_AUDIOLEN
# for slideshow: set length of slides; check menu length is long enough

if $DO_CAROUSEL; then
    # if user passed -bgaudio but did not -(sub)menu-length, use full audio
    if  [[ -n $BG_AUDIO ]] && ! $USER_MENU_LEN; then
        MIX_SLIDE_LEN=$(bc_math "$BG_AUDIOLENGTH / ${#MIX_IN[@]}")
    else # only use MENU_LEN seconds of audio ( default 20 secs unless passed )
         MIX_SLIDE_LEN=$(bc_math "${MENU_LEN[MENU_NUM-1]} / ${#MIX_IN[@]}")
    fi
    # subtract transition time from the slide length
    TT=1 # a constant value atm
    $SLIDE_FADE && MIX_SLIDE_LEN=$(bc_math "$MIX_SLIDE_LEN - $TT")

    if [[ $(bc -l <<< "$MIX_SLIDE_LEN == 0") -eq 1 ]]; then
        # use 2 frames for each still so MIX_SLIDE_LEN is not 0
        MIX_SLIDE_LEN=$(bc -l <<< "scale=3; 2 / $FRAME_RATE")
    elif [[ $(bc -l <<<  "$MIX_SLIDE_LEN < 0") -eq 1 ]]; then
        runtime_error "The menu length is not long enough for an animated menu.
        For slideshows where -bgaudio FILE is supplied, this is determined by:
        1. -menu-length argument if supplied
        2. length of the supplied -bgaudio
        you gave ${#MIX_IN[@]} files

        If -menu-length is not supplied, the length of the menu is the length
        the -bgaudio FILE, or 20 secs if silent background (no -bguaudio FILE)
        (Note: the fade effect duration is 1 second for each slide in the menu"
    fi
    MIX_ALEN=$MIX_SLIDE_LEN
    MIX_VFRAMES=$(bc_math "$MIX_SLIDE_LEN * $FRAME_RATE" int)
fi
# Check input files for compliance; offer to tovid-encode non-compliant files
# run this twice for switched menus for 1st menu made and last
# to make sure files get symlinked properly (Hack)
if [[ $MENU_NUM = [1-2] || -n ${file_is_image[@]}  ]]; then
    # do not check compliance for SVCD's - no still images are made
    if ! $MK_CAROUSEL_MODE; then
        echo
        check_compliance
        $GROUPING && check_compliance group
    fi
fi

# this is for getting slide files to BASEDIR
unset MPEGS2MOVE
for i in $WORK_DIR/*slide_grp*.mpg; do
    [[ -e $i ]] && \
    MPEGS2MOVE=( "${MPEGS2MOVE[@]}" "${i/slide_grp/group}")
done
for i in "${!FILES[@]}"; do
    # do not overwrite slideshows if making them
    if $SINGLE_SLIDESHOW \
     || { ${SLIDESHOW[i]} &&  [[ ${CAROUSEL[i]} != "carousel" ]] ; }; then
        MPEGS2MOVE=( "${MPEGS2MOVE[@]}" "$WORK_DIR/${TSET_NUM}-$((i+1)).mpg")
    fi
done
if { $GROUPING || $SINGLE_SLIDESHOW ; } && $TITLESET_MODE; then
    if ! $MK_CAROUSEL_MODE; then
        for i in ${!MPEGS2MOVE[@]}; do
            rm -f "$BASEDIR/${MPEGS2MOVE[i]##*/}"
            cp "${MPEGS2MOVE[i]}" "$BASEDIR"/
        done
    fi
fi
echo

# animated slideshows join the slides and can add audio (-bgaudio)
if $DO_CAROUSEL && ! $USE_DVD_SLIDESHOW; then
    for i in ${!MIX_IN[@]}; do
        this_item=${MIX_IN[i]##*/}
        for f in ${!FILES2BIN[@]}; do
            list_item=${FILES2BIN[f]##*/}
            if [[ $this_item = $list_item ]]; then
                F2BIN[i]="yes"
            fi
        done
    done
    IMGENC_CMD=(ffmpeg -f yuv4mpegpipe -r $FRAME_RATE -i - -s $VIDSIZE \
    $SS_FFMOPTS -r $FRAME_RATE -bf 2 -y "$WORK_DIR/slideshow.m2v")
    echo
    for p in ${!MIX_IN[@]}; do
        if [[ "${F2BIN[p]}" = "yes" ]]; then
            BINNING_CMD=(convert "${MIX_IN[p]}" -depth 8 \
            -resize $CAROUSEL_SIZE "$WORK_DIR/${p}.ppm")
            # BINNING_CMD modified after get_binning_cmd() if imaage>1440 etc
            get_binning_cmd $p "${MIX_IN[p]}"
            spin "Binning slide $((p+1))"
            "${BINNING_CMD[@]}"  >> "$LOG_FILE" 2>&1
            MIX_IN[p]="$WORK_DIR/${p}.ppm"
        fi
        # resize to $CAROUSEL_SIZE

        # do not blur the file twice if already binned and blurred
        [[ ${F2BIN[p]} = "yes" ]] && unset SLIDEBLUR[p]
        if [[ $SBORDER_ARG || $SLIDE_FRAME ]]; then
            tmbnail_size=$(( 640 - SFRAME_ARG - (SBORDER_ARG * 2) ))
            if $USERS_BACKGROUND && [[ -n $BACKGROUND ]]; then
                SLD_BG="$WORK_DIR/slide_bg.ppm"
                convert "$BACKGROUND" -gravity center -crop 640x480+0+0 \
                 +repage -resize 640x480\! "$SLD_BG"
            else
                SLD_BG="xc:#101010"
            fi
            spin "Bordering and framing slide $((p+1))"
            border_and_frame "${MIX_IN[p]}" "$WORK_DIR/${p}.ppm"
            MIX_IN[p]="$WORK_DIR/${p}.ppm"
        fi
        cursize=$(identify -ping -format %wx%h "${MIX_IN[p]}")
        if (( ${cursize/x*} !=  ${CAROUSEL_SIZE/x*} )) \
        || (( ${cursize/*x} !=  ${CAROUSEL_SIZE/*x} )); then
            spin "Resizing slide $((p+1))"
            convert "${MIX_IN[p]}" -depth 8 \
            -resize ${CAROUSEL_SIZE}!  ${SLIDE_BLUR[p]} "$WORK_DIR/${p}.ppm"
            MIX_IN[p]="$WORK_DIR/${p}.ppm"
        fi
    done
    echo
    sstime1=$(date +%s)
    # make a fifo to send raw yuv to, to be encoded by ffmpeg
    mkfifo "$WORK_DIR/ppm.fifo"
    "${IMGENC_CMD[@]}" 2>/dev/null < "$WORK_DIR/ppm.fifo" &
    encpids="$encpids $!"
    #exec 3> "$WORK_DIR/ppm.fifo"

    if [[ $EFFECT = "fade" ]]; then
        [[ $TV_STANDARD = "ntsc" ]] && fade_frames=15 || fade_frames=12
        fade_incr=$(bc -l <<< "scale=2; 100 / $fade_frames") >&2
        convert -size ${CAROUSEL_SIZE}! xc:'#101010' -depth 8 \
        "$WORK_DIR/black.ppm"
    elif [[ $EFFECT = "crossfade" ]]; then
        [[ $TV_STANDARD = "ntsc" ]] && fade_frames=30 || fade_frames=25
        fade_incr=$(bc -l <<< "scale=2; 100 / $fade_frames") >&2
    fi

    TOYUV_FADE_CMD=(ppmtoy4m -v 0 -n $fade_frames -A 10:11 -F $YUV_FR -I p \
    -S 420mpeg2 -r)
    TOYUV_STILLS_CMD=(ppmtoy4m -n $MIX_VFRAMES -A 10:11 -F $YUV_FR -I p \
    -S 420mpeg2 -r )
    # transitions
    echo >&2

    for f in ${!MIX_IN[@]}; do
        base_ppm="$WORK_DIR/${f}.ppm"
        if [[ $EFFECT = "crossfade" ]]; then
            if ((f == (${#MIX_IN[@]} - 1) )); then
                overlay_ppm="$WORK_DIR/0.ppm"
            else
                overlay_ppm="$WORK_DIR/$((f+1)).ppm"
            fi
        fi
        # encode fadein frames - keep yuv header
        if [[ $EFFECT = "fade" ]]; then
            spin "Doing fadein for slide $((f+1))" >&2
            # yuvcorrect (remove headers) if we are not on 1st slide fadein
            ((f==0)) && YUVCORRECT="cat"
            do_transitions fadein
            # encode transition frames
            cat "$WORK_DIR"/animenu/*.ppm 2>/dev/null |
            "${TOYUV_FADE_CMD[@]}" 2>/dev/null | $YUVCORRECT 2>/dev/null
            rm -f "$WORK_DIR"/animenu/*.ppm
        fi
        # encode still frames
        # need yuvcorrect if for fade style (remove headers)
        [[ $EFFECT = "fade" ]] && YUVCORRECT="yuvcorrect -T NO_HEADER"
        if [[ $EFFECT = "crossfade" ]]; then
            # encoding 1st slide
            if ((f==0)); then
                YUVCORRECT="cat"
            else # subsequent slides and fades need header removed
                YUVCORRECT="yuvcorrect -T NO_HEADER"
            fi
        fi
        spin "Doing stills for slide $((f+1))" >&2
        "${TOYUV_STILLS_CMD[@]}" "${MIX_IN[f]}" 2>/dev/null |
        $YUVCORRECT 2> /dev/null
        # now we need yuvcorrect for everything
        YUVCORRECT="yuvcorrect -T NO_HEADER"
        # do a transition to the next slide
        [[ $EFFECT = "fade" ]] && fadetype=fadeout || fadetype="crossfade"
        spin "Doing $fadetype for slide $((f+1))" >&2
        if [[ $EFFECT = "crossfade" ]]; then
            do_transitions crossfade
        elif [[ $EFFECT = "fade" ]]; then
            do_transitions fadeout
        fi
        # encode transition frames
        if (($f == (${#MIX_IN[@]} - 1) )); then
            fadein_cmd=(ppmtoy4m -v 0 -n 26 -A 10:11 -I p -r -S 420mpeg2)
            cat "$WORK_DIR"/animenu/*.ppm 2>/dev/null |
            "${fadein_cmd[@]}" 2>/dev/null |
            $YUVCORRECT 2> /dev/null
        else
            cat "$WORK_DIR"/animenu/*.ppm 2>/dev/null|
            "${TOYUV_FADE_CMD[@]}" 2>/dev/null | $YUVCORRECT 2> /dev/null
        fi
        rm -f "$WORK_DIR"/animenu/*.ppm
        # do crossfade looping to 1st slide if doing crossfade effect
        if (($f == (${#MIX_IN[@]} - 1) )); then
            if [[ $EFFECT = "crossfade" ]]; then
                spin "Looping back to slide 1 with crossfade" >&2
                base_ppm=${MIX_IN[0]}
                do_transitions crossfade
                # encode transition frames
                cat "$WORK_DIR"/animenu/*.ppm 2>/dev/null |
                "${TOYUV_FADE_CMD[@]}" 2>/dev/null | $YUVCORRECT 2> /dev/null
                rm -f "$WORK_DIR"/animenu/*.ppm
            fi
        fi
    done > "$WORK_DIR/ppm.fifo"
    # close the pipe
    #exec 3>&-
    sstime2=$(date +%s)
    enctime=$(( sstime2 - sstime1 ))
    enctime=$(format_seconds $enctime)
    echo
    echo "todisc took $enctime to do the slideshow"
    if $MK_CAROUSEL_MODE; then
        # move the m2v to BASEDIR (basedir of -carousel_menu_mode)
        echo
        mv -v "$WORK_DIR/slideshow.m2v" "$BASEDIR/carousel-${CAROUSEL_NUM}.m2v"
        cleanup
        exit 0
    fi

    # get length
    bgaudio_time=$(vid_length "$WORK_DIR/slideshow.m2v")

    if [[ -n $BG_AUDIO ]]; then
        # convert background audio to wav
        BGAUDIO_CMD=(ffmpeg -i "$BG_AUDIO" -t $bgaudio_time -ar 48000 \
         -acodec pcm_s16le -y $WORK_DIR/slideshow.wav)
    else
        # generate silence
        BGAUDIO_CMD=(ffmpeg -f s16le -t $bgaudio_time -i /dev/zero -ar 48000 \
        -ac 2 -acodec pcm_s16le -y $WORK_DIR/slideshow.wav)
    fi
    echo
    echo "Encoding audio to wav with: ${BGAUDIO_CMD[@]}" | format_output |
    tee -a "$LOG_FILE"
    echo
    "${BGAUDIO_CMD[@]}" >> "$LOG_FILE" 2>&1
    # fade wav if background audio used and user did not disable fading
    if [[ -n $BG_AUDIO ]] && $AUDIO_FADE; then
        sox "$WORK_DIR/slideshow.wav" "$WORK_DIR/slideshow-faded.wav" \
         fade t $FADE $bgaudio_time $FADE
        rm -f "$WORK_DIR/slideshow.wav"
        mv "$WORK_DIR/slideshow-faded.wav" "$WORK_DIR/slideshow.wav"
    fi

    # convert the wav to target format
    echo
    echo "Converting wav to $TARGET format"
    BGAUDIO_CMD=(ffmpeg -i "$WORK_DIR/slideshow.wav" \
     $AUDIO_OPTS -y "$WORK_DIR/slideshow.ac3")
    echo "Runnning ${BGAUDIO_CMD[@]}" | tee -a "$LOG_FILE"
    "${BGAUDIO_CMD[@]}" | format_output >> "$LOG_FILE" 2>&1
    echo
    # multiplex to mpeg-2 ( svcd or dvd )
    MPLEX_CMD=(mplex -V -f $MPLEX_FORMAT -o "$WORK_DIR/slideshow.mpg" \
    "$WORK_DIR/slideshow.$AUDIO_EXT" "$WORK_DIR/slideshow.m2v")
    yecho
    echo "Running ${MPLEX_CMD[@]}" |format_output |tee -a "$LOG_FILE"
    "${MPLEX_CMD[@]}" |format_output >> "$LOG_FILE" 2>&1
    yecho
    if [[ -s "$WORK_DIR/slideshow.mpg" ]]; then
        mv "$WORK_DIR/slideshow.mpg" "$WORK_DIR/intro.mpg"
    else
        runtime_error "The joined slideshow file was not created"
    fi

fi

if $DO_CAROUSEL && $USE_DVD_SLIDESHOW; then
    [[ -n $BG_AUDIO ]] && SS_AUDIO=(-a "${BG_AUDIO[@]}" )
    if [[ -n $SLIDESHOW_CONF ]]; then
        cp -v "$SLIDESHOW_CONF" "$WORK_DIR/dvd-slideshow.conf"
    else
        mk_dvd_slideshow_conf "${MIX_IN[@]}"
    fi
    dvd-slideshow $NO_SMP $vid_type -n slideshow -o "$WORK_DIR" \
    "${SS_AUDIO[@]}" -f "$WORK_DIR/dvd-slideshow.conf"
    mv "$WORK_DIR/slideshow.vob" "$WORK_DIR/intro.mpg"
fi
# check bgvideo and showcase VIDEO for compliance ( if present ) #FIXME
if [[ -n $BG_VIDEO ]]; then
    # do not reencode animated slideshow made in MK_CAROUSEL_MODE
    if ! [[ $BG_VIDEO = $WORK_DIR/carousel-00.m2v ]]; then
        if ! idvid -isformat \
         ${TV_STANDARD}-${TARGET} "$BG_VIDEO" >/dev/null; then
            tovid_reencode "$BG_VIDEO" $BG_SEEK background
        fi
    fi
elif [[ -n $SHOWCASE_VIDEO ]]; then
    # do not reencode animated slideshow made in MK_CAROUSEL_MODE
    if ! [[ $SHOWCASE_VIDEO = $WORK_DIR/carousel-00.m2v ]]; then
        if ! $SWITCHED && ! $QUICK_MENU; then
            if ! idvid -isformat \
            ${TV_STANDARD}-${TARGET} "$SHOWCASE_VIDEO" >/dev/null; then
                tovid_reencode "$SHOWCASE_VIDEO" $SHOWCASE_SEEK_VAL showcase
            fi
        fi
    fi
fi

# symlink IN_FILES in $WORK_DIR to solve some quoting issues for dvdauthor
if [[ $MENU_NUM -eq 1 ]]; then
    yecho "Symlinking files to $WORK_DIR"
    for i in ${!IN_FILES[@]}; do
        if ! [[ -e $BASEDIR/${TSET_NUM}-$((i+1)).mpg ]]; then
            (cd "$REAL_WORK_DIR" &&  ln -sf "${IN_FILES[i]}" \
             "$BASEDIR/${TSET_NUM}-$((i+1)).mpg")
        fi
    done
fi
$SINGLE_SLIDESHOW && echo "Getting stats on the slides now"
for ((i=0; i<${#IN_FILES[@]}; i++)); do
    if [[ $MENU_NUM -eq 1 ]]; then
        ! $SINGLE_SLIDESHOW && spin "Getting stats on ${IN_FILES[i]}"
        idvid_stats[i]=$(idvid -terse -accurate "${IN_FILES[i]}" 2>/dev/null)
    fi
    if [ -s  "${IN_FILES[i]}.nav_log" ]; then
        length[i]=$(awk 'END{print NR}' "${IN_FILES[i]}.nav_log")
    fi
done

if $GROUPING &&  [[ $MENU_NUM -eq 1 ]]; then
    echo
    echo ". . . Getting stats on grouped files now . . ."
    echo
    for u in ${!grouping[@]}; do
        CUR_VID=$(readlink -f "${grouping[u]}")
        spin "Getting stats on "${CUR_VID##*/}""
        group_idvid_stats[u]=$(idvid -terse -accurate "$CUR_VID" 2>/dev/null)
        if [ -s "$CUR_VID.nav_log" ]; then
            group_length[u]=$(awk 'END{print NR}' "$CUR_VID.nav_log")
        fi
    done
    echo
fi

# get length of videos in a separate loop from other stats
# if we are doing SVCD there will be no nav_seek file
for i in ${!IN_FILES[@]}; do
    # if we have a non empty nav_log get the length from that
    if [ -s "${IN_FILES[i]}".nav_log ]; then
        VID_LEN[i]=$(bc_math "${length[i]} / $FRAME_RATE")
    else # otherwise, we run mencoder to get the length
        VID_LEN[i]=$(vid_length  "${IN_FILES[i]}" )
    fi
    if [[ ${VID_LEN[i]%.*} -lt ${SEEK_VAL[i]%.*} ]]; then
        usage_error "A seek of ${SEEK_VAL[i]} seconds is too large for
        ${IN_FILES[i]}. The file is only ${VID_LEN[i]} seconds long"
    fi
    # check if file is long enough for the submenu length
    if $ANI_SUB_MENU; then
        if ((${VID_LEN[i]%.*} < (${SUBMENU_LEN[i]} * ${CHAPTERS[i]}) )); then
            usage_error "${IN_FILES[i]} is not long enough for ${CHAPTERS[i]}
                         animated submenu chapters of ${SUBMENU_LEN[i]} seconds"
        fi
    fi
    # add -force to makevcd if short file
    # wait for input on short files (slides) unless -video-pause passed
    if [[ $(bc -l <<< "${VID_LEN[i]} < 1") -eq 1 ]]; then
        [[ -z ${VPAUSE[i]} ]] && VPAUSE[i]="inf"
        # 1 chapter per short file, (altered below if group short file)
        ! $USER_CHAPTERS && CHAPTERS[i]=1 # each 'slide' is a chapter
    fi
done
# make sure we have the length of grouped files as well
for g in ${!grouping[@]}; do
    # if we have a value for ${group_length[g]}  get the length from that
    if [[ -n "${group_length[g]}" ]]; then
        GROUP_VID_LEN[g]=$(bc_math "${group_length[g]} / $FRAME_RATE")
    else # otherwise, we run mencoder to get the length
        GROUP_VID_LEN[g]=$(vid_length "${grouping[g]}")
    fi
done
if $GROUPING; then
    index=0
    for i in "${!IN_FILES[@]}"; do
        if [[ ${GROUP[i]} ]]; then
            iter=( $BASEDIR/${TSET_NUM}-group-$((i+1))-*.mpg )
            for ((t=index; t<index+${#iter[@]}; t++)); do
                # get lengths of group videos also in a seperate loop
                # concatenate the group lengths in a string
                GROUP_VID_LENGTHS[i]="${GROUP_VID_LENGTHS[i]} \
                ${GROUP_VID_LEN[t]}"
                # if short file, assume it is a slideshow, and use pause="inf"
                if [[ $(bc -l <<< "${GROUP_VID_LEN[t]} < 1") -eq 1 ]]; then
                    # but only if -group-video-pause was not passed
                    [[ -z ${GRP_VPAUSE[i]} ]] && GRP_VPAUSE[i]="inf"
                    ! $USER_CHAPTERS && CHAPTERS[i]=0 # each slide's a chapter
                fi
            # replacement for comma delimited locales
            done
            index=$((index+${#iter[@]}))
            unset iter
            # a string of the joined grouped lengths and 1st video in the group
            GROUP_VID_LENGTHS[i]="${VID_LEN[i]} ${GROUP_VID_LENGTHS[i]}"
            # total length for the whole group - for chapter creation
            GROUP_TOT_LEN[i]=$(awk_total <<< "${GROUP_VID_LENGTHS[i]}")
        fi
    done
fi
# put in the log file in case anyone is interested
if ! $VMGM_ONLY &&  [[ $MENU_NUM -eq 1 ]] && $DO_STATS; then
    get_stats files
    echo
fi
if ! $VMGM_ONLY &&  [[ $MENU_NUM -eq 1 ]] && $GROUPING && $DO_STATS; then
    get_stats group
    echo; echo $SEPARATOR
fi
echo

# run quick_menu to create an almost finished menu file ( intro.m2v )
$QUICK_MENU && quick_menu
# if doing switched menus, use the bgaudio from each video
# unless "none" is passed for -bgaudio
if $SWITCHED; then
    yecho
    let vid=MENU_NUM-1
    SHOWCASE_SEEK_VAL=${SEEK_VAL[vid]}
    # use silence if a short file ( probably a slide ) and no background audio
    if [[ -z $BG_AUDIO &&  $( bc -l <<< "${VID_LEN[vid]} < 1") -eq 1 ]]; then
        BG_AUDIO="none"
    fi
    # if no audio is detected in the video
    if grep -q "A_NOAUDIO=:" <<< "${idvid_stats[vid]}"; then
        # if -bgaudio is not passed, or passed as 'none', use silence
        if [[ -z $BG_AUDIO || $BG_AUDIO = "none" ]]; then
            yecho "Using silence as audio background for ${FILES[vid]}"
        # if -bgaudio is passed, use the provided file
        else
            yecho "Using $BG_AUDIO as audio background for "${FILES[vid]}""
        fi
    else # audio detected in the video
        if [[ -z $BG_AUDIO && $BG_AUDIO != "none" ]]; then
            # use the audio from each video for each switched menu
            BG_AUDIO=${IN_FILES[vid]}
            if $STATIC; then
                [[ -z $MENU_AUDIOLEN ]] \
                && MENU_AUDIOLEN=${MENU_LEN[MENU_NUM-1]}
                # start audio at the beginning unless user passes -bgaudio-seek
                ! $USER_BG_AUDIO_SEEK && BG_AUDIO_SEEK=0
                # make sure MENU_AUDIOLEN value isn't longer than the video
                # FIXME if video shorter than menu length adjust MENU_LEN
                [[ $( bc -l <<< "$MENU_AUDIOLEN > ${VID_LEN[vid]}") -eq 1 ]] \
                                            && MENU_AUDIOLEN=${VID_LEN[vid]}
                # MENU_LEN can't be longer than the audio length
                # don't use fade unless the video is long enough to support it
                [[ $(bc -l <<< "${VID_LEN[vid]} < (($FADE * 2) + 2)") \
                -eq 1 ]] && AUDIO_FADE=false
            else
                # same seek value as video unless user passes -bgaudio-seek
                ! $USER_BG_AUDIO_SEEK && BG_AUDIO_SEEK=${SEEK_VAL[vid]}
                # the menu audio will be the same length as the switched video
            fi
            yecho "Using audio from "${FILES[vid]}" for the audio background,"
            ! $STATIC && yecho \
            "using the same seek value for the audio as the video"
            yecho "If you wish to use silence for the switched menu,"
            yecho "use '-bgaudio none'"
        else
            if [[ $BG_AUDIO = "none" ]]; then # no audio if -bgaudio none
                BG_AUDIO=""
                MENU_AUDIOLEN=2
                AUDIO_FADE=false
            else # BG_AUDIO="$BG_AUDIO" if -bgaudio supplied and not 'none'
                [[ -z $MENU_AUDIOLEN ]] && \
                MENU_AUDIOLEN=${MENU_LEN[MENU_NUM-1]}
                yecho \
                "Using "$BG_AUDIO" as audio background for $SHOWCASE_VIDEO"
            fi
        fi
    fi
    yecho
fi
for ((i=0; i<${#VID_LEN[@]}; i++)); do
    NEW_LENGTH=( ${NEW_LENGTH[@]}   ${VID_LEN[i]%.*} )
done
# find out longest video and shortest video
for ((i=0; i<${#NEW_LENGTH[@]}; i++)); do
    val=${NEW_LENGTH[i]}
    [ -z "$MAX_VAL" ] || ((val > MAX_VAL)) && MAX_VAL=$val && max_key=$i
    if $ANI_SUB_MENU; then
        [ -z "$MIN_VAL" ]  || ((val < MIN_VAL)) && MIN_VAL=$val && min_key=$i
    fi
done
# if submenu selected, translate seconds of submenu length into # of frames
if $ANI_SUB_MENU; then
    for i in ${!IN_FILES[@]}; do
        SUBMENU_FRAMES+=( $(bc_math "$FRAME_RATE * ${SUBMENU_LEN[i]}" int) )
    done
fi
# if animated submenu check if videos are long enough for the # of chapters
if $ANI_SUB_MENU; then
    for ((i=0; i<=NUM_FILES; i++)); do
        S=$(bc_math "${SEEK_VAL[i]} * $FRAME_RATE" int)
        F=$(bc_math  "${CHAPTERS[i]} * 0" int )
        V=$(bc_math "${VID_LEN[i]} * $FRAME_RATE" int)
        if [ $((V - S)) -le $F ] ; then
            echo "Sorry, you can not use ${CHAPTERS[i]}
            chapters for ${IN_FILES[i]}.  Maximum chapters for this video
            (using a -seek of ${SEEK_VAL[i]}):
            $(bc_math "($V - $S) / ${SUBMENU_FRAMES[i]}" int) chapters" |
             format_output
            exit 1
        fi
        unset V F
    done
fi
# allow animated menus of length of longest video
MAX_MENU_LEN=$(bc_math "$FRAME_RATE * ${MENU_LEN[MENU_NUM-1]}" int)
MAX_VAL_FRAMES="$((MAX_VAL * 30))"

MENU_FRAMES=$MAX_MENU_LEN
if $STATIC; then
    if $SWITCHED && [[ -z $BG_VIDEO ]] && ! $MENU_FADE; then
        FRAMES=1
    elif [[ -z $BG_VIDEO && -z $SHOWCASE_VIDEO ]] && ! $MENU_FADE; then
        FRAMES=1
    else
        FRAMES=$MENU_FRAMES
    fi
    # THUMB_FRAMES is for extracting frames from video titles
    # a static menu can have animated bg or showcase video
    THUMB_FRAMES=1
else
    FRAMES=$MENU_FRAMES
    THUMB_FRAMES=$FRAMES
fi
# if -transition-to-menu used, the bg ends when the thumbs start to fade in
if $TRANSITION_TO_MENU; then
    BG_VIDEO_FRAMES=$THUMBS_FADEIN_ENDFRAME
else
    BG_VIDEO_FRAMES=$FRAMES
fi
# menu-fade only processes up to the THUMBS_FADEOUT_ENDTIME set previously
LAST_PIC=${LAST_PIC:-$FRAMES}

###############################################################################
#                           End of info block                                 #
###############################################################################

###############################################################################
#                       work on the clip title images                         #
###############################################################################
# extract images from the title videos

if ! $TEXTMENU && ! $SINGLE_SLIDESHOW && $DO_MENU; then
    echo
    echo "Creating $THUMB_FRAMES images from each video for the main menu"
    for ((i=0; i<=NUM_FILES; i++)) ; do
        if [ "$SC_FRAMESTYLE" = "glass" ]; then
            # some vars for get_framed_pics()
            D=2
            VOUT="png:z=7"
            FRAME_SIZE=$THUMB_SIZE
            echo "Using mplayer to get framed images from "${IN_FILES[i]}""
            OUT=$WORK_DIR/pics/$i
            echo "Working on "${IN_FILES[i]}""
            MPLAYER_SEEK_VAL=${SEEK_VAL[i]}
            get_framed_pics "${IN_FILES[i]}"   >> "$LOG_FILE" 2>&1
            echo
            for ((p=1; p<=$THUMB_FRAMES; p++)); do
                mv  "$WORK_DIR"/$(printf "%08d%s" $p .png) \
                  $WORK_DIR/pics/$i/$(printf "%06d%s" $p .png) 2>/dev/null
            done
        elif [[ ${file_is_image[i]} = "yes" ]]; then
            spin "Convert ${FILES[i]} to proper size/format"
            convert "${FILES[i]}" -depth 8 \
              -resize ${THUMB_SIZE}! \
              "$WORK_DIR/pics/$i/$(printf "%06d%s"  0 .${IMG_FMT})"
        else
            echo
            echo "Working on ${IN_FILES[i]}"
            if [ -s  "${IN_FILES[i]}.nav_log" ]; then
                NAV_SEEK[i]="--nav_seek"
                NAVSEEK[i]=${IN_FILES[i]}.nav_log
            fi

            TRANSCODE_CMD2=(nice transcode $transcode_arg 10 \
            --write_pid $WORK_DIR/tcode$i.pid -q 1 -i "${IN_FILES[i]}" \
            -c ${SEEK_FRAMES[i]}-$((${SEEK_FRAMES[i]} + $THUMB_FRAMES)) \
            ${NAV_SEEK[i]} "${NAVSEEK[i]}" -o "$WORK_DIR/pics/$i/" \
            -f $FRAME_RATE -Z $THUMB_SIZE $EXPORT)
            yecho "Running ${TRANSCODE_CMD2[@]}" | fold -bs

            run_transcode()
            {
                "${TRANSCODE_CMD2[@]}" >> "$LOG_FILE"  2>&1
                sleep 1
            }
            run_transcode &
            sleep 1 # short sleep to allow 1st jpg to appear
            TRANSCODE_PID=$(<$WORK_DIR/tcode$i.pid)
            tcode_pids="$tcode_pids $TRANSCODE_PID"
            check_stall $TRANSCODE_PID &
            if [[ -n "$TRANSCODE_PID" ]]; then
                while ps -p $TRANSCODE_PID >/dev/null; do
                    sleep 2 # spinner interval
                    last_image=$(find $WORK_DIR/pics/$i \
                    -maxdepth 1 -name \*.$IMG_FMT| sort |
                    awk -F / '{ field = $NF }; END{ print field }')
                spin "Seeking in video and creating images: $last_image"
                done
                echo
                numpics=$(find $WORK_DIR/pics/$i/ -name  "*.${IMG_FMT}" | wc -l)
                # which video has the most frames encoded? Used in final encode
                ((numpics > ani_pics)) && ani_pics=$numpics
                echo "Created $numpics images of $THUMB_FRAMES"
            else
                runtime_error "Problem creating images from the video."
            fi
            unset TRANSCODE_CMD2 run_transcode numpics
        fi
    done
fi
# create the pics for background image
if $DO_MENU; then
    if [ -z "$BG_PIC" ]; then
        echo
        echo "Creating a black background"
        BG_PIC="$WORK_DIR/pics/template.jpg"
        if $QUICK_MENU; then
            convert  -size $VIDSIZE xc:none "$BG_PIC"
        else
            convert  -size $VIDSIZE xc:$BG_CLR "$BG_PIC"
        fi
    else
        convert -size $VIDSIZE "$BG_PIC" -resize $VIDSIZE! \
        "$WORK_DIR/pics/template.jpg"
    fi
    # create/resize submenu background, fill in array and symlink if needed
    if $SUB_MENU; then
        if [[ -n ${SM_BACKGROUND[@]} ]]; then
            if ((${#SM_BACKGROUND[@]} > 1)); then
                for f in ${!SM_BACKGROUND[@]}; do
                    convert  -size $VIDSIZE "${SM_BACKGROUND[f]}" \
                    -resize $VIDSIZE\! miff:- |
                    convert - "$SM_BK_PNG" -gravity SouthEast -geometry +50+50 \
                    -composite "$WORK_DIR/submenu$((f+1))_template.jpg"
                done
            else
                convert  -size $VIDSIZE "$SM_BACKGROUND" \
                -resize $VIDSIZE\! miff:- |
                convert - "$SM_BK_PNG" -gravity SouthEast -geometry +50+50 \
                -composite "$WORK_DIR/submenu_template.jpg"
            fi
        else
            convert  -size $VIDSIZE xc:$SUBMENU_BG_CLR miff:- |
            convert - "$SM_BK_PNG" -gravity SouthEast -geometry +50+50 \
            -composite "$WORK_DIR/submenu_template.jpg"
        fi
        if  ((${#SM_BACKGROUND[@]} == 1)) || [[ -z ${SM_BACKGROUND[@]} ]]; then
            for ((f=0; f<${#IN_FILES[@]}; f++)); do
                ln -s "$WORK_DIR/submenu_template.jpg" \
                "$WORK_DIR/submenu$((f+1))_template.jpg"
                SM_BACKGROUND[f]=$WORK_DIR/submenu$((f+1))_template.jpg
            done
        fi
    fi
    echo
fi
# chapters and submenu xml stuff
# this block does not run if user passing HH:MM:SS chapters
if [[ -n ${CHAPT_ARRAY[@]} ]]; then
    :
else
    for ((s=0; s<=NUM_FILES; s++)); do
        # make chapter points for videos, divide by $CHAPTERS to get
        # chapter lengths, then get running totals
        CHAPT_INTERVALS[s]=$(bc_math "${VID_LEN[s]} / ${CHAPTERS[s]}")
        # <TODO if GROUPING:  for group chapter thumbs feed group
        # chapter points to transcode in a loop as normal, but output
        # to different subdirs. Then rename according to frame number
        # moving all to the same subdir. Then follow usual procedure,
        # moving  into chapter subdirs for final montages  /TODO>

        # and format in HH:MM:SS
        L=( ${L[@]} $(for ((i=1; i<${CHAPTERS[s]}; i++)) ; \
        do echo "${CHAPT_INTERVALS[s]}";done) )
        chapt_intervals="0 $(running_total <<< ${L[@]})"
        chapters="$(for c in $chapt_intervals; \
        do echo $(format_seconds $c); done)"
        # replace commas for comma delimited locales
        if [ ${CHAPTERS[s]} = 1 ]; then chapters="00:00:00.000"; fi
        CHAPTS=$(for i in $chapters; do echo -n $i,;done)
        CHAPT_ARRAY[s]="${CHAPTS%?}" # %? to remove trailing ','
        unset L cmd
    done
fi
# slideshows can have submenus - these spu buttons are for videos only (inc_files)
if $SUB_MENU; then
    for ((s=0; s<=NUM_FILES; s++)); do
        if ! ${SLIDESHOW[s]}; then
            echo
            echo "Creating highlight and select PNGs for submenu $((s + 1))"
            C=$((${CHAPTERS[s]} - 1))
            MENU_BUTTON_SIZE=${GEO_ARRAY[C]}
            get_button_geo
(
cat  <<EOF
rectangle 2,2 $GEO
EOF
)  > $WORK_DIR/draw_file${s}
            convert +antialias -size ${GEO_ARRAY[C]}+5+5 \
            xc:none -fill none -stroke "$SELECT_CLR" -strokewidth 4 \
            -draw @draw_file${s} "$WORK_DIR/Submenu${s}_Selectx1.png"
            convert +antialias -size ${GEO_ARRAY[C]}+5+5 \
            xc:none -fill none -stroke "$HLIGHT_CLR" -strokewidth 4 \
            -draw @draw_file${s} "$WORK_DIR/Submenu${s}_Highlightx1.png"
        fi
        CMD1=(montage -background none \
        $(for ((i=0; i<=C; i++)); do
        echo $WORK_DIR/Submenu${s}_Selectx1.png;done) \
        -bordercolor none -mattecolor transparent \
        -tile ${TILE_ARRAY[C]} \
        -geometry ${GEO_ARRAY[C]}+5+5 \
        -background none miff:-)
        CMD2=(montage -background none \
        $(for ((i=0; i<=C; i++)); do
        echo $WORK_DIR/Submenu${s}_Highlightx1.png;done) \
        -bordercolor none -mattecolor transparent \
        -tile ${TILE_ARRAY[C]} \
        -geometry ${GEO_ARRAY[C]}+5+5 \
        -background none miff:-)
        CMD3=(convert +antialias -size $VIDSIZE xc:none  \
        - -gravity north -geometry +0+45 -composite \
        "$WORK_DIR/sm_back_${HLIGHT_CLR/\#}.png" \
        -gravity SouthEast -geometry +50+50 -composite )
        CMD4=(convert +antialias -size $VIDSIZE xc:none  \
        - -gravity north -geometry +0+45 -composite \
        "$WORK_DIR/sm_back_${SELECT_CLR/\#}.png" \
        -gravity SouthEast -geometry +50+50 -composite )
        if ! ${SLIDESHOW[s]}; then
            "${CMD1[@]}" | "${CMD4[@]}" $WORK_DIR/Submenu${s}_Select.png
            "${CMD2[@]}" | "${CMD3[@]}" $WORK_DIR/Submenu${s}_Highlight.png
        else
            ! [[ -e "$WORK_DIR/Playall.png" ]] && \
             mk_play_button "#C6C6C6" '#101010' \
             default "$WORK_DIR/Playall.png"
            # make the button for spumux too
            mk_play_button  "$HLIGHT_CLR" "$HLIGHT_CLR" spu \
            "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png"
            mogrify -channel A -threshold 50% \
            "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png"
            mk_play_button   "$SELECT_CLR" "$SELECT_CLR" spu \
            "$WORK_DIR/Playall_${SELECT_CLR/\#}.png"
            mogrify -channel A -threshold 50% \
            "$WORK_DIR/Playall_${SELECT_CLR/\#}.png"
            convert +antialias -size $VIDSIZE xc:none \
            "$WORK_DIR/Playall_${SELECT_CLR/\#}.png" \
            -gravity SouthEast -geometry +50+50 -composite \
            "$WORK_DIR/Submenu${s}_Select.png"
            convert +antialias -size $VIDSIZE xc:none \
            "$WORK_DIR/Playall_${HLIGHT_CLR/\#}.png" \
            -gravity SouthEast -geometry +50+50 -composite \
            "$WORK_DIR/Submenu${s}_Highlight.png"
        fi
        for button in Select Highlight; do
            # the slideshow 'play' button is more likely to need this
            if ${SLIDESHOW[s]}; then
                mogrify -channel A -threshold 50% \
                "$WORK_DIR/Submenu${s}_${button}.png"
            fi
            num_colours=$(identify -ping -format %k \
            "$WORK_DIR/Submenu${s}_${button}.png")
            ((num_colours >3)) && \
            mogrify -channel A -threshold 99% \
            "$WORK_DIR/Submenu${s}_${button}.png"
        done

        # make submenu spumux.xml
(
    cat <<EOF
<subpictures>
   <stream>
     <spu force="yes" start="00:00:00.0"
          highlight="$WORK_DIR/Submenu${s}_Highlight.png"
          select="$WORK_DIR/Submenu${s}_Select.png"
          autooutline="infer"
          autoorder="rows"/>
   </stream>
 </subpictures>
EOF
) > "$WORK_DIR/submenu$((s + 1))_spumux.xml"
    done
fi

# debug chapters
if ! $VMGM_ONLY &&  [[ $MENU_NUM -eq 1 ]] && $DO_STATS; then
    echo
    for ((i=0; i<=NUM_FILES; i++)); do
        ! ${SLIDESHOW[i]} && \
        echo -e "Chapters for "${IN_FILES[i]}" are: \n"${CHAPT_ARRAY[i]}"\n"
    done
fi
# get button coordinates if text-rect buttons (showcase menu only)
if [[ $BUTTON_STYLE = *text* ]] && $SHOWCASE; then
    for ((i=0; i<=NUM_FILES; i++)); do
        xdim=${TT_DIM[i]%%x*}
        ydim=${TT_DIM[i]##*x}
        X0=${SC_TITLES_X_ARRAY[i]}
        ! $TEXTMENU && X0=$( cut -f2 -d+ <<< ${THUMBTITLES_ARRAY[i]})
        X1=$((X0 + xdim))
        Y0=${SC_TITLES_Y_ARRAY[i]}
        Y1=$((Y0 + ydim))
        ((X0%2 && X0--)); ((Y0%2 && Y0--))
        ((X1%2 && X1++)); ((Y1%2 && Y1++))
        button_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\")
        $SHOWCASE && btn_geos[i]=${button_geos[@]}
        unset button_geos
    done
fi
if [[ "$BUTTON_STYLE" = "text" && -z "$OUTLINEWIDTH" ]]; then
    OUTLINEWIDTH="\"14\""
else
    [[ -z "$OUTLINEWIDTH" ]] && OUTLINEWIDTH="\"6\""
fi
# the spumux here doc starts loops at 1, so NUM_BUTTONS has an extra index
if { $TSET_MODE && $VMGM_MENU ; } || \
 { $PLAYALL ||  { $TITLESET_MODE && $VMGM_MENU ; } ; }; then
    NUM_BUTTONS=$(( ${#FILES[@]} + 1 ))
else
    NUM_BUTTONS=${#FILES[@]}
fi
# no FILES for VMGM menu (titleset arrangements): use ${#TITLES[@]}
$VMGM_ONLY && NUM_BUTTONS=${#TITLES[@]}
$VMGM_ONLY && $PLAYALL && ((NUM_BUTTONS++))
$SWITCHED && SPUMUX_XML="$BASEDIR/spumux.xml"
if $SWITCHED; then
    down="down=\"ActionDown\"" && up="up=\"ActionUp\""
    right="right=\"ActionDown\"" && left="left=\"ActionUp\""
    updown="down=\"ActionDown\" up=\"ActionUp\""
fi
(
    cat <<EOF
$( { $SHOWCASE || $SINGLE_SLIDESHOW ; } && closebracket='>'
echo -e "<subpictures>"
echo -e  "  <stream>"
echo -e    "    <spu force=\"yes\" start=\"$START\"$END"
echo -e "         highlight=\"$WORK_DIR/Highlight.png\""
echo -e "         select=\"$WORK_DIR/Select.png\"$closebracket"
if ! $SHOWCASE && ! $SINGLE_SLIDESHOW; then
    echo -e "         autooutline=\"infer\""
    echo -e "         outlinewidth="$OUTLINEWIDTH""
    echo -e "         autoorder=\"$AUTOORDER\">"
fi)
$(if $QUICK_NAV && $SINGLE_SLIDESHOW; then
    echo -n "       <button name=\"1\" ${btn_geos[0]} "
    echo -e "       left=\"ActionLeft\" right=\"ActionRight\"/>"
    echo -e "        <action name=\"ActionLeft\"/>"
    echo -e "        <action name=\"ActionRight\"/>"
    if { $TITLESET_MODE || $TSET_MODE ; } && $VMGM_MENU; then
        echo -e "        <button name=\"2\"  ${btn_geos[1]} up=\"1\"/>"
    fi
elif $QUICK_NAV; then
    for ((i=1; i<=NUM_BUTTONS; i++)); do
        ! $SWITCHED_MENUS && \
        right="right=\"$((i+1))\"" && left="left=\"$((i-1))\""
        # $i -eq 1 should cover ((NUM_FILES==0)) situation
        if [[ $i -eq 1 ]]; then
            echo -n \
             "       <button name=\"$i\" ${btn_geos[i-1]} $down $up"
        elif ((i==NUM_FILES+1)); then
            if  $PLAYALL || $VMGM_MENU; then
                # no playall or vmgm button for vmgm menu
                dwn="down=\"$((i+1))\""
                echo -n \
                 "       <button name=\"$i\" ${btn_geos[i-1]} $up $dwn"
            else
                echo -n "       <button name=\"$i\" ${btn_geos[i-1]} $down $up"
            fi
        else
            ((i != NUM_FILES+2)) && \
            echo -e \
             "       <button name=\"$i\" ${btn_geos[i-1]} $left $right $down $up/>"
        fi
        if ((i==1)); then
            if ((NUM_FILES==0)); then # special case if only 1 file on menu
                echo -e " left=\"ActionLeft\" right=\"ActionRight\"/>"
                echo -e "       <action name=\"ActionLeft\"/>"
                echo -e "       <action name=\"ActionRight\"/>"
                if $SWITCHED_MENUS; then
                    echo -e "       <action name=\"ActionDown\"/>"
                    echo -e "       <action name=\"ActionUp\"/>"
                fi
            else
                echo -e " left=\"ActionLeft\" $right/>"
            fi
        elif ((i==NUM_FILES+1)) && ((NUM_FILES != 0)); then
            echo -e " right=\"ActionRight\" $left/>"
            echo -e "       <action name=\"ActionLeft\"/>"
            echo -e "       <action name=\"ActionRight\"/>"
            if $SWITCHED_MENUS; then
                echo -e "       <action name=\"ActionDown\"/>"
                echo -e "       <action name=\"ActionUp\"/>"
            fi
        fi
        if ((i==NUM_FILES+2)); then # quick-nav assumes titlesets
            # VMGM_MENU means NOT -no-vmgm
            if $VMGM_MENU && $PLAYALL && ! $VMGM_ONLY; then #DEBUG
                echo -n "       <button name=\"$i\" ${btn_geos[i-1]} "
                echo -e "up=\"$((i-1))\" down=\"$((i+1))\"/>"
                echo -e "       <button name=\"$((i+1))\" ${btn_geos[i]} $down/>"
            elif $PLAYALL; then # PLAYALL only
                echo -e "       <button name=\"$i\" ${btn_geos[i-1]} $down/>"
            else # vmgm button only
                echo -e "       <button name=\"$i\" ${btn_geos[i]} $down/>"
            fi
        fi
    done
fi)
$(if $SWITCHED && ! $QUICK_NAV; then
    for ((i=1; i<=NUM_BUTTONS; i++)); do
        if ((i==NUM_FILES+2)); then # extra button: Playall, or Return, or both
            if $TITLESET_MODE && $VMGM_MENU && $PLAYALL; then
                echo -n "       <button name=\"$i\" ${btn_geos[i-1]} "
                echo -e "up=\"$((i-1))\"/>"
                echo -e "       <button name=\"$((i+1))\" ${btn_geos[i]} $down/>"
            elif { $TITLESET_MODE && $VMGM_MENU ; }; then # Return only
                echo -n "       <button name=\"$i\" ${btn_geos[i]} "
                echo -e "up=\"$((i-1))\" $down/>"
            elif $PLAYALL; then # Playall only
                echo -n "       <button name=\"$i\" ${btn_geos[i-1]} "
                echo -e "up=\"$((i-1))\" $down/>"
            fi
        elif ((i==NUM_FILES+1)); then
            if ($TITLESET_MODE && $VMGM_MENU) || $PLAYALL; then
                echo -n "       <button name=\"$i\"  ${btn_geos[i-1]} "
                echo -e "$up down=\"$((i+1))\"/>"
            else
                echo -e "       <button name=\"$i\" ${btn_geos[i-1]} $updown/>"
            fi
        else
            echo -e "       <button name=\"$i\"  ${btn_geos[i-1]} $updown/>"
        fi
    done
    echo -e "       <action name=\"ActionDown\"/>"
    echo -e "       <action name=\"ActionUp\"/>"
fi)
$(if ! $SWITCHED && ! $QUICK_NAV; then
    if $SINGLE_SLIDESHOW; then
        echo -e "      <button name=\"1\" ${btn_geos[0]}/>"
        if $TITLESET_MODE && $VMGM_MENU; then
            echo -e "      <button name=\"2\" ${btn_geos[1]}/>"
        fi
    else
        for ((i=1; i<=NUM_BUTTONS; i++)); do
            if $SHOWCASE && [[ $NUM_FILES -ge $SPLIT ]]; then
                if ((i>SPLIT)) && ((i<NUM_BUTTONS)); then
                    left="left=\"$((i-SPLIT))\""; right=""
                elif  (( i<=SPLIT)) && (( (i+SPLIT) <= (NUM_FILES+1) )); then
                    right="right=\"$((i+SPLIT))\""; left=""
                else
                    left=""; right=""
                fi
            fi
            if ((i==NUM_FILES+2)); then
                if $TITLESET_MODE && $VMGM_MENU && $PLAYALL; then
                    # both Return button AND Playall buttons
                    echo -e \
                    "      <button name=\"$i\" $right $left ${btn_geos[i-1]}/>"
                    echo -e \
                    "      <button name=\"$((i+1))\" $right $left ${btn_geos[i]}/>"
                elif $PLAYALL; then
                    # Playall button only
                    echo -e \
                    "      <button name=\"$i\" $right $left ${btn_geos[i-1]}/>"
                elif $TITLESET_MODE && $VMGM_MENU; then
                    # Return button only
                    echo -e \
                    "      <button name=\"$i\" $right $left ${btn_geos[i]}/>"
                fi
            else # all other buttons besides Playall and Return
                echo -e \
                "      <button name=\"$i\" $right $left ${btn_geos[i-1]}/>"
            fi

        done
    fi
fi)
    </spu>
  </stream>
</subpictures>
EOF
) |sed '/^ *$/d'  > "$SPUMUX_XML"

if $SUB_MENU; then
    JUMP=menu
    POST="        <post> jump cell 1; </post>"
    if $ANI_SUB_MENU; then
        PAUSE=" pause=\"$PAUSE_TIME\""
    else
        PAUSE=" pause=\"inf\""
        unset POST
    fi
else
    JUMP=title
fi
# make dvdauthor.xml
# REGISTERS: g1: switched menus, g2: vmgm intro, g3: -quick-nav, g4: playall
# g5: button highlight, g6: VMGM button highlight, g7: vmgm playall
# g8: toggle showing if a video finished playing (used with g7)
# Note: for switched menus g1 is used for 'button highlight', not g5

# TSET_NUM is the titleset number being worked on
# ALLTITLES is an array of the number of titles in each titleset
# NUM_MENUS is the # of menus being made
# menu_num is the current menu being worked on
# the above 2 values always equal 1 unless doing switched menus
# TSET_NUM supplied by the calling todisc script and is the current titleset #
MENU_FILE="$BASEDIR/animenu${TSET_NUM}-${MENU_NUM}.mpg"
$DO_INTRO && SET_REG="if ( g2 eq 1 ) "
VMGM_PREJUMP="${SET_REG}jump titleset 1 menu;"
#$DO_INTRO && VMGM_POST="<post>g2=1; jump titleset 1 menu;</post>"
$VMGM_ONLY && MENU_FILE="$BASEDIR/VMGM.mpg"
$SWITCHED_MODE && ! $VMGM_ONLY \
&& MENU_FILE="$BASEDIR/animenu${TSET_NUM}-${MENU_NUM}.mpg"
if $PLAYALL || $VMGM_PLAYALL; then
    AUTHOR_PLAYALL=: # needed for VMGM playall logic
fi

$SWITCHED_MENUS && NUM_MENUS=${#FILES[@]} || NUM_MENUS=1
! $AUTHOR && DVDAUTHOR_XML="$BASEDIR/dvdauthor.xml"
# this 1st block (if $AUTHOR) refers to the VMGM of single titleset DVD's only
(
    cat <<EOF
$(if $AUTHOR; then
    echo     "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    echo     "<dvdauthor dest=\"$OUT_DIR\" jumppad=\"0\">"
    echo -e  "  <vmgm>\n    <menus>"
    echo     "      <video aspect=\"4:3\"/>"
    echo     "      <pgc entry=\"title\" pause=\"0\">"
    echo     "        $INTRO"
    echo     "        <vob file=\"$WORK_DIR/dummy.mpg\"/>"
    echo     "        <pre>"
    echo     "        if ( g5 eq 0 ) g5=1; g4=0;"
    $SWITCHED_MENUS && \
    echo     "        if (g1 eq 0) g1=1;"
    echo     "        $VMGM_PREJUMP"
    echo     "        </pre>"        
    $DO_INTRO && \
    echo     "        <post>g2=1; jump titleset 1 menu;</post>"
    echo -e  "      </pgc>\n    </menus>\n  </vmgm>"
fi)
  <titleset>
    <menus>
      <video aspect="4:3"/>
$(for ((menu_num=1; menu_num<=NUM_MENUS; menu_num++)); do
    echo -e "      <pgc>"
    for ((i=1; i<=$V_TOTAL; i++)); do
        if $SUB_MENU; then
            JUMP_INC=$((i + NUM_MENUS))
        else
            JUMP_INC=$i
        fi
        if $SINGLE_SLIDESHOW; then
            :
        else
            if $VIDEOS_ARE_CHAPTERS && [[ -z ${grouping[@]} ]]; then
                echo -e \
                "        <button name=\"$i\">g5=$i; jump title 1 chapter $i;</button>"
            else
                echo -e \
                 "        <button name=\"$i\">g5=$i; jump $JUMP $JUMP_INC;</button>"
            fi
        fi
    done
    if $QUICK_NAV; then
        (( TSET_NUM == 1 )) && PREV=$TSET_TOT || PREV=$(( TSET_NUM - 1 ))
        (( TSET_NUM == TSET_TOT )) && NEXT=1 || NEXT=$(( TSET_NUM + 1))
        (( TSET_NUM == 1 )) && Ind=$((TSET_TOT-1)) || Ind=$(( TSET_NUM - 2 ))
    fi
    if $SINGLE_SLIDESHOW; then
        echo -e "        <button name=\"1\">jump title 1;</button>"
    fi
    if $QUICK_NAV; then
        echo -e "        <button name=\"ActionLeft\">"
        echo -e "        g1=${ALLTITLES[Ind]}; g5=${ALLTITLES[Ind]}; g3=$PREV; button=1024;"
        echo -e "        jump vmgm menu entry title;</button>"
        echo -e "        <button name=\"ActionRight\">"
        echo -e "        g1=1; g5=1; g3=$NEXT; button=1024;"
        echo -e "        jump vmgm menu entry title;</button>"
    fi
    if $SINGLE_SLIDESHOW; then
        if  $TITLESET_MODE && $VMGM_MENU; then
            echo -n "        <button name=\"2\">g2=1; g3=1000; g6=$TSET_NUM; jump vmgm menu;"
            echo -e "</button>"
        fi
    fi
    if $SWITCHED_MENUS; then
        if [[ $menu_num -eq $NUM_MENUS ]]; then
            inc=1
        else
            inc=$((menu_num+1))
        fi
        [[ $menu_num -eq 1 ]] && dec=$NUM_MENUS || dec=$((menu_num - 1))
        echo -e "        <button name=\"ActionUp\">g1=$dec; jump menu $dec;</button>"
        echo -e "        <button name=\"ActionDown\">g1=$inc; jump menu $inc;</button>"
    fi
    NAV_BTN_NUM=$V_TOTAL
    if $PLAYALL ; then # titleset playall has button here: not for $VMGM_PLAYALL
        ((NAV_BTN_NUM++))
        echo -e "        <button name=\"$NAV_BTN_NUM\">g4=1; jump title 1 chapter 1;</button>"
    fi
    if  $TITLESET_MODE && $VMGM_MENU && ! $SINGLE_SLIDESHOW; then
        ((NAV_BTN_NUM++))
        echo -e "        <button name=\"$NAV_BTN_NUM\">g2=1; g3=1000; g6=$TSET_NUM; jump vmgm menu;</button>"
    fi
    echo -e "        <vob file=\"$BASEDIR/animenu${TSET_NUM}-${menu_num}.mpg\" pause=\"$VMGM_PAUSE\"/>"
    if $SWITCHED_MENUS; then
        if [[ $menu_num -ne $NUM_MENUS ]]; then
            echo -e "        <pre>"
            echo -e "        button = g1 * 1024;"
            echo -e "        if (g1 ne $menu_num) jump menu $((menu_num+1)); g4=0;"
            echo -e "        if (g8==0) { g7=0; g4=0; }"
            echo -e "        if (g7==$TSET_NUM) { g4=1; jump title 1 chapter 1; }"
            echo -e "        </pre>"
        else
            echo -e "        <pre>button = g1 * 1024; g4=0;</pre>"
        fi
    else
        if $SINGLE_SLIDESHOW; then
            echo -e "        <pre>if (g5 gt 1) g5=1; button = g5 * 1024;</pre>"
        else
            if $VMGM_PLAYALL; then
                echo "        <pre>"
                echo "        button = g5 * 1024;"
                echo "        if (g8==0) { g7=0; g4=0; }"
                echo "        if (g7==$TSET_NUM) { g4=1; jump title 1 chapter 1; }"
                echo "        </pre>"
            else
                echo -e "        <pre>button = g5 * 1024; g4=0;</pre>"
            fi
        fi
    fi
    echo -e "$MAIN_PRE"
    echo -e "$MAIN_POST"
    echo -e "      </pgc>"
done)
$(if $SUB_MENU; then
    echo -ne "      <pgc>\n"
        for ((Y=1; Y<=$V_TOTAL; Y++)); do
            if ${SLIDESHOW[Y-1]}; then
                echo -e "        <button name=\"1\">jump title $Y;</button>"
            else
                for ((g=1; g<=${CHAPTERS[Y-1]}; g++)); do
                    echo -e "        <button name=\"$g\">jump title $Y chapter $g;</button>"
                done
                echo -e "        <button name=\"$g\">jump menu 1;</button>"
            fi
            echo -e "        <vob file=\"$BASEDIR/${TSET_NUM}-Menu$Y.mpg\"$PAUSE/>"
echo "$POST"
            echo "      </pgc>"
            echo "      <pgc>"
        done | sed '$d'
fi)
    </menus>
    <titles>
      $TITLES_VID_TAG
$(if [[ -n ${LANGS[@]} ]]; then
    for ((s=0; s<${#LANGS[@]}; s++)); do
        echo -e "      <audio lang=\"${LANGS[s]}\"/>"
    done
fi)
$(if $SUBTITLES; then
    for ((s=0; s<${#SUBS_ARRAY[@]}; s++)); do
        echo -e "      <subpicture lang=\"${SUBS_ARRAY[s]}\"/>"
    done
fi)
$(if $SINGLE_SLIDESHOW || $VIDEOS_ARE_CHAPTERS; then
    echo -e "      <pgc>"
fi)
$(z=1;for ((i=0; i<${#IN_FILES[@]}; i++)); do
    vid_pause=""; grp_vid_pause=""
    [[ -n ${VPAUSE[i]} ]] && vid_pause="pause=\"${VPAUSE[i]}\""
    [[ -n ${GRP_VPAUSE[i]} ]] && grp_vid_pause="pause=\"${GRP_VPAUSE[i]}\""
    unset j
    if $SINGLE_SLIDESHOW || $VIDEOS_ARE_CHAPTERS; then
        :
    else
        echo -e "      <pgc>"
    fi
    if [[ -n $AUDIO_CHANNEL ]]; then
        echo "${VOB_PRE[i]}"
    fi
    if [[ -n ${GROUP[i]} ]]; then
       ((MENU_NUM == 1 && ${CHAPTERS[i]} != 0)) && get_group_chapters $i format
        if ((${nochapt[i]})); then
            ! ${SLIDESHOW[i]} && echo -e \
             "        <vob file=\"$BASEDIR/${TSET_NUM}-$((i+1)).mpg\" $vid_pause/>"
            for ((m=1; m<=$((${GROUP[i]})); m++)); do
                mpg="$BASEDIR/${TSET_NUM}-group-$((i+1))-${m}.mpg"
                [[ -e $mpg ]] && \
                echo -e "        <vob file=\"$mpg\" $grp_vid_pause/>"
            done
        else
            ! ${SLIDESHOW[i]} && echo -e \
             "        <vob file=\"$BASEDIR/${TSET_NUM}-$((i+1)).mpg\" $chpts0 $vid_pause/>"
            for ((m=1; m<=$((${GROUP[i]})); m++)); do
                mpg="$BASEDIR/${TSET_NUM}-group-$((i+1))-${m}.mpg"
                [[ -e $mpg ]] && echo -e \
                 "        <vob file=\"$mpg\" ${chpts[++j]} $grp_vid_pause/>"
            done
        fi
    else
        # this block runs for single slideshows
        # max 99 titles, else we make a new <pgc>
        echo -ne "        <vob file=\"$BASEDIR/${TSET_NUM}-$((i+1)).mpg\""
        echo -e  " chapters=\""${CHAPT_ARRAY[i]}"\" $vid_pause/>"
        if $SINGLE_SLIDESHOW && ((t==96 && i < NUM_FILES)); then
            echo -e "        <post>jump title $((++z));</post>"
            echo -e "      </pgc>"
            echo -e "      <pgc>"
            t=0
        else
            unset CHAIN_PP
        fi
    fi
    if $CHAIN_VIDEOS; then
        if [ "${POST_PLAY[i]}" = "chain" ]; then
            (( i < NUM_FILES )) && CHAIN_PP="jump title $((i + 2)) chapter 1"
            (( i == NUM_FILES )) && CHAIN_PP="jump title 1 chapter 1"
        else
            CHAIN_PP="call menu"
        fi
        if $AUTHOR_PLAYALL; then
            if [ $i -lt $NUM_FILES ]; then
                $VMGM_PLAYALL && echo "        <pre>g8=0;</pre>"
                echo -e "        <post>"
                $VMGM_PLAYALL && echo -e "        g8=1;"
                echo -e \
                  "        if (g4==1) jump title $((i+2)) chapter 1; $CHAIN_PP;"
                echo -e  "        </post>"
            else
                if $VMGM_PLAYALL; then
                    echo -e  "        <pre>g8=0;</pre>"
                    echo     "        <post>"
                    echo     "        { if (g7>0) {"
                    echo     "              g8=1;"
                    echo -ne "              if (g7>=${TSET_TOT}) { g7=0; g4=0; } " 
                    echo -e  "else g7=$((TSET_NUM+1));"
                    echo     "              call vmgm menu entry title;"
                    echo     "              }"
                    echo -e  "        }"
                    echo -e  "        call menu;"
                    echo -e  "        </post>"
                else
                    echo -e "        <post>call menu;</post>"
                fi
            fi
        else
            echo -e "        <post>$CHAIN_PP;</post>"
        fi
    else
        if $AUTHOR_PLAYALL; then
            if [ $i -lt $NUM_FILES ]; then
                $VMGM_PLAYALL && echo "        <pre>g8=0;</pre>"
                echo -e "        <post>"
                $VMGM_PLAYALL && echo -e "        g8=1;"
                echo -e "        if (g4==1) jump title $((i+2)) chapter 1; call menu;"
                echo "        </post>"
            else
                if $VMGM_PLAYALL; then
                    echo     "        <pre>g8=0;</pre>"
                    echo     "        <post>"
                    echo     "        { if (g7>0) {"
                    echo     "              g8=1;"
                    echo -ne "              if (g7>=${TSET_TOT}) { g7=0; g4=0; } " 
                    echo     "else g7=$((TSET_NUM+1));"
                    echo     "              call vmgm menu entry title;"
                    echo     "              }"
                    echo     "        }"
                    echo     "        call menu;"
                    echo     "        </post>"
                else
                    echo     "        <post>call menu;</post>"
                fi
            fi
        else
            if $SINGLE_SLIDESHOW || $VIDEOS_ARE_CHAPTERS; then
                [[ $i = $NUM_FILES ]] && \
                 echo -e "        <post>call menu;</post>"
            else
                echo -e "        <post>call menu;</post>"
            fi
        fi
    fi
    if $SINGLE_SLIDESHOW || $VIDEOS_ARE_CHAPTERS; then
        :
    else
        echo -e "      </pgc>"
    fi
    ((t++)) # var for counting slides
done)
$( { $SINGLE_SLIDESHOW || $VIDEOS_ARE_CHAPTERS ; } &&
 echo -e "      </pgc>")
    </titles>
  </titleset>
$(if $AUTHOR; then
echo -e "</dvdauthor>"
fi)
EOF
) |sed '/^ *$/d' >> "$DVDAUTHOR_XML"
##############################################################################
#                            Animenu stuff                                   #
##############################################################################

# make dummy VMGM mpeg
if ! $TITLESET_MODE && ! $DO_TITLESETS; then
    make_dummy
fi
# do submenu 1st for debug purposes
# TODO use exec 2>> "$LOG_FILE" to save lines
if $SUB_MENU; then
    yecho
    yecho "Building submenus"
    yecho
    yecho "Creating images for each chapter"
    if [ -z "$SM_TITLES" ]; then
        if $MULTILINE_TITLE; then
            for i in ${!TITLES[@]}; do
                SM_TITLES[i]="${TITLES[i]//\\n/ }"
            done
        else
            SM_TITLES=("${TITLES[@]}")
        fi
    fi
    # if animated: the length of the submenu audio will be the -submenu-length
    # if static:
    #     No audio: it will be 2 seconds long
    #     Audio and -submenu-length given: -submenu-length
    #     Audio and no -submenu-length given: full length of the audio file
    if $SUBMENU_AUDIO; then
        if [[ -n $SM_AUDIO_FILE ]]; then
            SM_AUDIOLEN=$(audio_length "$SM_AUDIO_FILE")
        fi
        for ((i=0; i<=NUM_FILES; i++)); do
            [[ -n $SM_AUDIO_FILE ]] && SUBMENU_AUDIOLEN[i]=$SM_AUDIOLEN
            if $USER_SUBMENU_LEN; then
                SUBMENU_AUDIOLEN[i]=$( unformat_time ${SUBMENU_LEN[i]} )
            else
                if ${SLIDESHOW[i]}; then
                    yecho
                    spin "getting length of ${SM_AUDIO[i]} "
                    SUBMENU_AUDIOLEN[i]=$(audio_length "${SM_AUDIO[i]}")
                    SUBMENU_LEN[i]=${SUBMENU_AUDIOLEN[i]}
                else
                    SUBMENU_AUDIOLEN[i]=$( unformat_time ${SUBMENU_LEN[i]} )
                fi
            fi
            # SM_LOOPS is the # of frames for static menus
            SM_LOOPS[i]=$( bc \
             <<< "${SUBMENU_AUDIOLEN[i]} * $FRAME_RATE" 2>/dev/null)
            SM_LOOPS[i]=${SM_LOOPS[i]%.*}
        done
    else # we just use the menu length for generating silence
        if $ANI_SUB_MENU; then
            SUBMENU_AUDIOLEN[i]=${SUBMENU_LEN[i]}
        else
            SUBMENU_AUDIOLEN[i]=2
            for ((i=0; i<=NUM_FILES; i++)); do
                SM_LOOPS[i]=60
            done
        fi
    fi
    # if doing animated submenus, we need a 'carousel' (animated slideshow)
    # background or showcase carousel will not do, nor is it made if $STATIC
    if $ANI_SUB_MENU && ((sshows>=1)); then
        if ! carousel_menu_mode submenu; then
            yecho '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
            yecho "todisc encountered an error"
            cleanup && killall_instances
            exit 13
        fi
    fi
    for ((i=0; i<${#IN_FILES[@]}; i++)); do
        smframes=${SUBMENU_FRAMES[i]}
        if ! ${SLIDESHOW[i]}; then
            C=$((${CHAPTERS[i]} - 1))
            SN_BTN_XY=${GEO_ARRAY[C]} # button dimensions
            NUM_CHAPTERS=${CHAPTERS[i]}
            yecho "Creating a transparent title PNG"
            SMTITLE_CMD=(convert -size 620x300 xc:none -font "$SM_TITLE_FONT" \
            -pointsize $SUBMENU_FONTSIZE -fill "$SM_TITLE_CLR" \
            -draw "gravity center text 2,2 \"${SM_TITLES[i]}\"" \
            -stroke "$SUBMENU_STROKE" -strokewidth 1 \
            -fill "$SM_TITLE_CLR" -stroke "$SUBMENU_STROKE" \
            -draw "gravity center text 1,1 \"${SM_TITLES[i]}\"" )
            SMTITLE_TRIM_CMD=(convert $QUALITY -trim +repage - -blur 0x0.3 \
            $WORK_DIR/title${i}_txt.png)
            SMTITLE_FADE_CMD=(composite -blend 0x${SM_TITLE_OPACITY} \
            null: - -matte)
            if [[ -n $SM_TITLE_OPACITY ]]; then
                "${SMTITLE_CMD[@]}" miff:- | "${SMTITLE_FADE_CMD[@]}" miff:- |
                "${SMTITLE_TRIM_CMD[@]}"
            else
                "${SMTITLE_CMD[@]}" miff:- | "${SMTITLE_TRIM_CMD[@]}"
            fi

            # which is harmless as they get removed, but needs to be tweaked
            if $ANI_SUB_MENU; then
                JPEG2YUV_OPTS=(-n $smframes)
                PICS_IN=($WORK_DIR/animenu/%0d.$SM_IMG_FMT)
                PICS_OUT=($WORK_DIR/animenu/)
                CUT_TIME=$smframes
                JPEG_DIR="$WORK_DIR/animenu"
                SLEEP=1
                TOTAL_JPEGS=$(($smframes * ${CHAPTERS[i]}))

            else  # not animated submenu
                JPEG2YUV_OPTS=(-n 1 -l ${SM_LOOPS[i]})
                PICS_IN=($WORK_DIR/${i}-submenu.$SM_IMG_FMT)
                PICS_OUT=($WORK_DIR/submenu/)
                CUT_TIME=1
                JPEG_DIR="$WORK_DIR/submenu"
                SLEEP=.5
                TOTAL_JPEGS=${CHAPTERS[i]}
                PREFIX=${i}-
            fi
            if [[ -n ${GROUP[i]} ]]; then
                unset x CUT c FILE_IN
                # this will also take care of grouped USER_CHAPTERS
                BASE=$WORK_DIR/${TSET_NUM}-group
                unset grp_chapters
                get_group_chapters $i
                ! $USER_CHAPTERS && ! ((${nochapt[i]})) && CUT[0]=30 && FILE_IN[0]=${IN_FILES[i]}
                for g in ${!grp_chapters[@]}; do
                    for pt in ${grp_chapters[g]}; do
                        pnt=$(unformat_time $pt)
                        if ((g == 0)); then
                            FILE_IN+=( "${IN_FILES[i]}" )
                        elif  ((${nochapt[i]})); then
                            FILE_IN+=( ${BASE}-$((i+1))-${g}.mpg )
                        elif [[ $pnt = 0 || -z $pnt ]]; then
                            # user passed +0: no chapter point in this video
                            continue
                        else
                            FILE_IN+=( ${BASE}-$((i+1))-${g}.mpg )
                        fi
                        # do not get CUT frames if user passed +0
                        # nochapt[i] is : for -chapters 0 videos, use 00:00:00
                        if ! ((${nochapt[i]})) && \
                        { [[ $g != 0 && $pnt = 0 ]] || [[ -z $pnt ]] ; }; then
                            :
                        else
                            CUT+=( $( bc_math "$pnt * $FRAME_RATE" int) )
                        fi
                    done

                done
            elif $USER_CHAPTERS; then
                unset x CUT c_array
                # CHAPT_ARRAY is left in HH:MM:SS,HH:MM:SS format: unformat now
                c_array="${CHAPT_ARRAY[i]//,/ }"
                for v in $c_array; do
                    f=$(unformat_time $v)
                    CUT[x++]=$( bc_math "$f * $FRAME_RATE" int)
                done
            else
                # CHAPT_INTERVALS is seconds: "${VID_LEN[i]}/ ${CHAPTERS[i]}"
                counts=$(bc_math "${CHAPT_INTERVALS[i]} * $FRAME_RATE" int)
                numchpts=${CHAPTERS[i]}
                CUT=( 30 $(running_total <<< $(for ((a=0; a<numchpts; a++)); do
                echo -n "$counts ";done)) )
            fi
            for c in ${!CUT[@]}; do
                [[ -n ${CUT[c]} ]] && \
                cmd[c]=${CUT[c]}-$(bc_math "${CUT[c]} + $CUT_TIME" int)
            done
            if $USER_CHAPTERS; then
                # 1 second seek for 1st chapt (00:00:00), to avoid black frames
                cmd[0]=30-$(bc_math "30 + $CUT_TIME" int)
            elif [[ -z ${GROUP[i]} ]]; then
                # auto chapters needs the last seek removed
                key=$((${#cmd[@]} - 1))
                unset cmd[key]
            fi
            yecho
            yecho "Creating $TOTAL_JPEGS chapter images for ${IN_FILES[i]}"
            yecho
            unset cf frm
            for t in "${cmd[@]}"; do
                if [[ -n ${GROUP[i]} ]]; then
                    CUR_FILE="${FILE_IN[cf++]}"
                else
                    CUR_FILE="${IN_FILES[i]}"
                fi
                navlog=$(readlink -f "${CUR_FILE}").nav_log
                if [[ -s $navlog ]]; then
                    NAVSEEK="--nav_seek" && NAVLOG="$navlog"
                else
                    unset NAVSEEK NAVLOG
                fi

                TCODE_CMD=(nice transcode $transcode_arg 10 \
                --write_pid $WORK_DIR/tcode$i.pid -q 1 -i "$CUR_FILE" \
                $NAVSEEK "$NAVLOG" -o "${PICS_OUT[@]}" -f \
                $FRAME_RATE -Z ${GEO_ARRAY[C]},fast -c $t -y $SM_IMG_FMT,null)
                echo "Running ${TCODE_CMD[@]}" |
                sed 's/    */ /g'|sed -e "s/^ *//"|tee -a >> "$LOG_FILE"
                #sed 's/    */ /g'|sed -e "s/^ *//"|fold -bs >> "$LOG_FILE"
                echo >> "$LOG_FILE"
                run_transcode()
                {
                    "${TCODE_CMD[@]}" >> "$LOG_FILE"  2>&1
                    sleep 1
                }
                run_transcode &
                sleep 2 # short sleep to allow 1st jpg to appear
                TCODE_PID=$(<$WORK_DIR/tcode$i.pid)
                tcode_pids="$tcode_pids $TCODE_PID"
                check_stall $TCODE_PID &
                if [[ -n "$TCODE_PID" ]]; then
                    while ps -p $TCODE_PID >/dev/null; do
                        sleep $SLEEP # spinner interval
                        last_image=$(find "$JPEG_DIR" -maxdepth 1 -name \*.jpg |
                        sort | awk -F / '{ field = $NF }; END{ print field }')
                        spin "Seeking in video and creating images: $last_image"
                    done
                    echo
                    total_images=$(find "$JPEG_DIR" -name '*.jpg' | wc -l)
                    echo "Created $total_images JPEGS of $TOTAL_JPEGS"
                else
                    runtime_error "Problem creating images from the video."
                fi
                unset TCODE_CMD cmd run_transcode
                if ! $ANI_SUB_MENU ; then
                    echo
                    mv $WORK_DIR/submenu/000000.$SM_IMG_FMT \
                    $WORK_DIR/submenu/$(printf "%08d%s\n" $((frm++)) .$SM_IMG_FMT)
                    let frm+=1
                elif $ANI_SUB_MENU; then
                    echo "renaming images by frame number"
                    echo
                    u=${t/*-}; v=${t/-*}
                    for ((n=0; n<smframes; n++)); do
                       # if [ $v -eq ${CUT[0]} ]; then
                        mv $WORK_DIR/animenu/$(printf "%06d%s\n" $n .jpg) \
                        $WORK_DIR/animenu/$(printf \
                        "%08d%s\n" $((frm++ )) .jpg)
                        let frm+=1
                    done
                fi
            done
            # make the chapter titles if called for.  Shadow is hardcoded at #101010
            if [[ -n  ${CHAPTER_TITLES[@]} ]]; then
                echo "Making Chapter titles for Video $((i+1))"
                for ((a=0; a<${CHAPTERS[i]}; a++)); do
                    ctitle="$WORK_DIR/${TSET_NUM}-${i}-chapter${a}.png"
                    ctcmd=(convert -size 620x300 xc:none \
                    -font "$CHAPT_FONT" -pointsize ${CHAPT_FONTSIZE[i]} \
                    -fill '#101010'  -stroke '#101010' -gravity South \
                    -annotate +0+0 "${CHAPTER_TITLES[a+I]}" -fill $CHAPTER_CLR \
                    -stroke "$CHAPTER_STROKE" -strokewidth 1 \
                    -annotate +1+1 "${CHAPTER_TITLES[a+I]}")
                    ct_fade_cmd=(composite -blend 0x${CHAPTER_TITLES_OPACITY} \
                    null: - -matte)
                    ct_trim_cmd=(convert $QUALITY - -trim +repage "$ctitle")
                    if [[ -n $CHAPTER_TITLES_OPACITY ]]; then
                        "${ctcmd[@]}" miff:- | "${ct_fade_cmd[@]}" miff:- |
                        "${ct_trim_cmd[@]}"
                    else
                        "${ctcmd[@]}" miff:- | "${ct_trim_cmd[@]}"
                    fi
                    # make sure title fits
                    ctitle_dim=$(identify -ping -format %w "$ctitle")
                    if  (($ctitle_dim >= ${GEO_ARRAY[C]%x*} )); then
                        newdim=$(bc_math "${GEO_ARRAY[C]%x*} * .9" int)
                        convert $QUALITY "$ctitle" -resize ${newdim}x "$ctitle"
                    fi
                done
            fi
            if $ANI_SUB_MENU ; then
                # move submenu images to each subdir: $WORK_DIR/animenu/{0,1,2,etc}
                # or if making chapter titles, output to subdirs; rm original
                for ((a=0; a<${CHAPTERS[i]}; a++)); do
                    unset num_procs smpids curimgs
                    # 2>/dev/null to work around perplexing spawned xterm bug
                    pics=($(find $WORK_DIR/animenu/ -maxdepth 1 -name \
                    00\*.$SM_IMG_FMT|sort 2>/dev/null|
                    head -n $smframes 2>/dev/null))
                    if [[ -n  ${CHAPTER_TITLES[@]} ]]; then
                        # title the chapters for submenu if needed
                        ctitle="$WORK_DIR/${TSET_NUM}-${i}-chapter${a}.png"
                        spin "Working on Video $((i+1)): chapter $((a+1))  "
                        for f in ${pics[@]}; do
                            if [[ -s $f ]]; then
                                ((num_procs++))
                                { convert -size ${GEO_ARRAY[C]} "$f" "$ctitle" \
                                -gravity south -geometry +0+5 -compose over \
                                -composite "$WORK_DIR/animenu/$a/${f##*/}" ; } &
                                smpids="$smpids $!"
                                if ((num_procs==max_procs)); then
                                    wait $smpids
                                    unset num_procs smpids
                                fi
                                # rm -f "$f"
                            fi
                        done
                        wait && rm -f "${pics[@]}"
                    else # no chapter titles
                        # moving images from Video $((i+1)) into subdirectories
                        for f in ${pics[@]}; do
                            mv "$f" $WORK_DIR/animenu/$a
                        done
                    fi
                    unset pics
                done
                # clean up left over pics in animenu/ dir
                rm -f $WORK_DIR/animenu/*.$SM_IMG_FMT
            fi

            if $ANI_SUB_MENU; then
                $DEBUG && stime=$(date +%s)
                TOYUV_CMD=(ppmtoy4m -v 0 -n $smframes -A 10:11 -F $YUV_FR -I p \
                -S 420mpeg2 -r)
                IMGENC_CMD=(ffmpeg -f yuv4mpegpipe -r $FRAME_RATE -i - -an \
                -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
                -y "$WORK_DIR/menu$i.m2v")
                echo
                yecho "Running ${TOYUV_CMD[@]} < $WORK_DIR/ppm.fifo |
                ${IMGENC_CMD[@]}" | fold -bs
                mkfifo "$WORK_DIR/ppm.fifo" 2>/dev/null
                mkfifo "$WORK_DIR/enc.fifo" 2>/dev/null
                "${TOYUV_CMD[@]}" < "$WORK_DIR/ppm.fifo" > \
                "$WORK_DIR/enc.fifo" 2>/dev/null &
                encpids="$encpids $!"
                "${IMGENC_CMD[@]}" <  "$WORK_DIR/enc.fifo"  2>/dev/null &
                encpids="$encpids $!"
                echo
                echo "Encoding $smframes frames for "${IN_FILES[i]}"" >&2
                # make fifos for intermediary piping
                for ((f=1; f<=max_procs; f++)); do
                    [[ ! -p "$WORK_DIR/temp-${f}.ppm" ]] && \
                     mkfifo "$WORK_DIR/temp-${f}.ppm"
                done
                unset smpids  num_procs
                for ((a=1; a<$smframes; a++)); do
                    ((num_procs++))
                    out_ppm="$WORK_DIR/temp-${num_procs}.ppm" # current frame
                    for ((b=0; b<${CHAPTERS[i]}; b++)); do
                        IMGS=( "${IMGS[@]}" $(find $WORK_DIR/animenu/$b \
                        -name \*.$SM_IMG_FMT| sort 2>/dev/null | head -n $a |
                        sed -n -e "$a p") )
                    done
                    IM_CMD=(convert "${IMGS[@]}" -bordercolor '#6E6E6E' \
                    -border $THUMB_FRAME_SIZE miff:-)
                    IM_CMD1=(montage - -tile ${TILE_ARRAY[C]} \
                    -geometry ${GEO_ARRAY[C]}+5+5 -bordercolor '#101010' \
                    -mattecolor '#101010' -background none miff:-)
                    IM_CMD2=(convert -depth 8 \
                    $WORK_DIR/submenu$((i+1))_template.jpg \
                    $WORK_DIR/title${i}_txt.png  -gravity south \
                    -geometry +0+55 -composite - -gravity north \
                    -geometry +0+45 -composite "$out_ppm")
                    { "${IM_CMD[@]}" | "${IM_CMD1[@]}" | "${IM_CMD2[@]}" ; } \
                    2>> "$LOG_FILE" &
                    smpids="$smpids $!"
                    ppm_fifos+=("$out_ppm") # all frames waiting to be processed
                    if ((num_procs==max_procs || a == smframes-1 )); then
                        spin "\rProcessing frame $((a+1)) of $smframes  " >&2
                        cat "${ppm_fifos[@]}"
                        wait $smpids
                        unset smpids num_procs ppm_fifos
                    fi

                    unset IMGS TOYUV_CMD IMGENC_CMD
                done > "$WORK_DIR/ppm.fifo"
                $DEBUG && etime=$(date +%s) && get_elapsed "the submenu m2v"

                # wait for ppmtoyuv and ffmpeg to finish
                wait

                unset IM_CMD IM_CMD2 d f P

            else # not $ANI_SUB_MENU

                yecho
                yecho "Making montage images for "${IN_FILES[i]}""
                # just use $CHAPTERS number of images
                imgs=( $(find $WORK_DIR/submenu -name \*.$SM_IMG_FMT |
                sort| head -n $NUM_CHAPTERS) )
                # title the chapter thumbs if titles supplied
                if [[ -n  ${CHAPTER_TITLES[@]} ]]; then
                    for P in "${!imgs[@]}"; do
                    curimage=$(awk -F / '{ print $NF }' <<< "${imgs[P]}")
                    spin "\rProcessing $curimage  "
                    ctitle="$WORK_DIR/${TSET_NUM}-${i}-chapter${P}.png"
                        sm_title_cmd=(convert "${imgs[P]}" \
                        "$ctitle" -gravity south -geometry +0+5 \
                        -compose over -composite  "${imgs[P]}"  )
                        "${sm_title_cmd[@]}" | tee -a "$LOG_FILE"
                    done
                fi
                IM_CMD=(convert "${imgs[@]}" -bordercolor '#6E6E6E' \
                -border $THUMB_FRAME_SIZE miff:-)
                IM_CMD1=(montage - -tile ${TILE_ARRAY[C]} -geometry \
                ${GEO_ARRAY[C]}+5+5 -background none miff:-)
                IM_CMD2=(convert $WORK_DIR/submenu$((i+1))_template.jpg \
                $WORK_DIR/title${i}_txt.png  -gravity south -geometry +0+55 \
                -composite - -gravity north -geometry +0+45 -composite \
                $WORK_DIR/${i}-submenu.$SM_IMG_FMT)
                "${IM_CMD[@]}" | "${IM_CMD1[@]}" | "${IM_CMD2[@]}"
            fi
            if ! $ANI_SUB_MENU; then

                yecho
                yecho "Converting chapter montage of ${IN_FILES[i]}
                to m2v video format"
                IMG_STREAM_CMD1=(jpeg2yuv -v 0 -f $FRAME_RATE -I p \
                "${JPEG2YUV_OPTS[@]}" -L 1 -b 1  -j "${PICS_IN[@]}")
                ENC_CMD1=(ffmpeg -f yuv4mpegpipe -r $FRAME_RATE -i - \
                -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
                -y "$WORK_DIR/menu$i.m2v")
                echo "Running ${IMG_STREAM_CMD1[@]} | ${ENC_CMD1[@]}"|
                format_output | tee -a "$LOG_FILE" 2>&1
                if ! "${IMG_STREAM_CMD1[@]}" |
                "${ENC_CMD1[@]}" 2>&1|strings >> "$LOG_FILE"; then
                    runtime_error
                fi
            fi

            # check if m2v was created ok before proceeding
            if mencoder -quiet -oac pcm -ovc copy -frames 0 \
            "$WORK_DIR/menu$i.m2v" -o /dev/null &>/dev/null; then
                :
            else
                echo
                runtime_error  \
                "The submenu video (m2v) does not appear to have been created"
            fi
            # clean out submenu dirs of images
            echo
            echo "Cleaning up leftover pics in $REAL_WORK_DIR/animenu"
            rm -f $WORK_DIR/submenu/*
            find $WORK_DIR/animenu/ -maxdepth 1 -type f -exec rm -f {} \;
            if $ANI_SUB_MENU; then
                find $WORK_DIR/animenu/[0-9]*/ -type f -exec rm -f {} \;
            fi
            # increment submenu titles index
            I=$((I+NUM_CHAPTERS))
        else # it is a slideshow
            # mv carousel.m2v or polaroid stack appropriately
            if $ANI_SUB_MENU; then
                cp $WORK_DIR/carousel-$((i+1)).m2v $WORK_DIR/menu${i}.m2v
            else
                yecho "Making a 'polaroid stack' of your slides"
                mk_polaroid_stack "$WORK_DIR"/${TSET_NUM}-slide_grp-$((i+1))-*.mpg &
                polaroid_pid=$!
                while ps -p $polaroid_pid >/dev/null; do
                    sleep .5
                    spin $SPINNER
                done
                echo
                #cp "$WORK_DIR/polaroid_stack.png"
                #ss_ind=$(awk -F[-.] '{print $2}' <<< "$sld")
                IM_CMD=(convert $WORK_DIR/submenu$((i+1))_template.jpg \
                "$WORK_DIR/polaroid_stack.png" \
                -gravity north -geometry +0+45 -composite \
                $WORK_DIR/thumb_title${i}.png \
                -gravity south -geometry +0+55 -composite \
                "$WORK_DIR/Playall.png" \
                -gravity SouthEast -geometry +50+50 -composite \
                -depth 8 "$WORK_DIR/polaroid_stack${i}.ppm")
                "${IM_CMD[@]}"

                # encode to m2v
                yecho "Encoding to compliant m2v video format"
                PPM_CMD=(ppmtoy4m -v 0 -n ${SM_LOOPS[i]} -A 10:11 -I p -F $YUV_FR \
                -S 420mpeg2 -r)
                FFM_CMD=(ffmpeg $INSIZE -r $FRAME_RATE -pix_fmt yuv420p \
                -f yuv4mpegpipe -i - -an -r $FRAME_RATE -s $VIDSIZE \
                -tvstd $TV_STANDARD $FFMPEG_OPTS -y "$WORK_DIR/menu${i}.m2v")
                yecho "Running ${PPM_CMD[@]} | ${FFM_CMD[@]}" | format_output
                cat "$WORK_DIR/polaroid_stack${i}.ppm" |
                "${PPM_CMD[@]}" | "${FFM_CMD[@]}" 2>&1 | strings >> "$LOG_FILE"
            fi
        fi
    done
    unset IMG_STREAM_CMD1 ENC_CMD1 JPEG2YUV_OPTS
    for ((s=0; s<=NUM_FILES; s++)); do
        # create audio background for either animated or plain submenus
        yecho
        yecho "Creating an audio background"
        yecho "Working on submenu audio for "${IN_FILES[s]}""
        if $SUBMENU_AUDIO; then # user supplied audio file for ths video
            if [[ -n "$SM_AUDIO_FILE" ]]; then # user supplied "1" audio file
                COPY_AC3=(cp -v $WORK_DIR/submenu.$AUDIO_EXT \
                $WORK_DIR/menu$s.$AUDIO_EXT)
                BGAUDIO_CMD=(ffmpeg -i "$SM_AUDIO_FILE" \
                -t ${SUBMENU_AUDIOLEN[s]} -ar 48000 -acodec pcm_s16le \
                -y $WORK_DIR/submenu.wav)
            elif [[ "${SM_AUDIO[s]}" = "none" ]]; then # user asked for silence
                SUBMENU_AUDIOLEN[s]=$(vid_length "$WORK_DIR/menu$s.m2v")
                BGAUDIO_CMD=(ffmpeg -f s16le -i /dev/zero $AUDIO_OPTS \
                -t ${SUBMENU_AUDIOLEN[s]} -y $WORK_DIR/menu$s.$AUDIO_EXT)
            else
                # SM_AUDIO[s] is an audio file we will process it
                # do separate wavs for each supplied audio bg for each submenu
                BGAUDIO_CMD=(ffmpeg -i "${SM_AUDIO[s]}" \
                -t ${SUBMENU_AUDIOLEN[s]} -ar 48000 -acodec pcm_s16le \
                -y $WORK_DIR/menu$s.wav)
                BGAUDIO_CMD2=(ffmpeg -i $WORK_DIR/menu$s.wav \
                $AUDIO_OPTS -y $WORK_DIR/menu$s.$AUDIO_EXT)
            fi
        else # no supplied audio for submenu so create silence
            SUBMENU_AUDIOLEN[s]=$(vid_length "$WORK_DIR/menu$s.m2v")
            BGAUDIO_CMD=(ffmpeg -f s16le -i /dev/zero $AUDIO_OPTS \
            -t ${SUBMENU_AUDIOLEN[s]} -y $WORK_DIR/menu$s.$AUDIO_EXT)
        fi
        # run if wav doesn't exist, or its a slideshow
        if [[ ! -s $WORK_DIR/submenu.wav ]] || ${SLIDESHOW[s]}; then
            yecho "Running ${BGAUDIO_CMD[@]}"
            # run command, error out if problem
            ! "${BGAUDIO_CMD[@]}" 2>&1 |strings >> "$LOG_FILE" 2>&1 \
            && runtime_error "Problem getting audio for the submenu"
        fi
        # convert to DVD/SVCD format as long as not "none" or single audio file
        if $SUBMENU_AUDIO \
        && [[ ! "${SM_AUDIO[s]}" = "none" && -z "$SM_AUDIO_FILE" ]]; then
            if $SM_AUDIO_FADE; then
                #TIME=$(audio_length "$WORK_DIR/menu$s.wav")
                echo -e "Running:
                sox $WORK_DIR/menu$s.wav $WORK_DIR/menu$s-processed.wav fade t
                $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE" |
                sed 's/    */ /g' | format_output
                sox -q $WORK_DIR/menu$s.wav $WORK_DIR/menu$s-processed.wav \
                 fade t $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE
                rm $WORK_DIR/menu$s.wav
                mv $WORK_DIR/menu$s-processed.wav $WORK_DIR/menu$s.wav
            fi
            echo "Running "${BGAUDIO_CMD2[@]}"" | fold -bs >> "$LOG_FILE"
            ! "${BGAUDIO_CMD2[@]}" 2>&1 |strings >> "$LOG_FILE" \
            && runtime_error "Problem getting audio for the submenu"
            unset TIME
        fi
        # if "1" audio file, then convert it if it has not been done yet
        if [[ -n "$SM_AUDIO_FILE" \
        && ! -s $WORK_DIR/submenu-processed.wav ]]; then
            if $SM_AUDIO_FADE; then
                #TIME=$(audio_length "$WORK_DIR/submenu.wav")
                echo -e "Running:
                sox $WORK_DIR/submenu.wav $WORK_DIR/submenu-processed.wav \
                fade t $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE" |
                format_output >> "$LOG_FILE"

                sox -q $WORK_DIR/submenu.wav $WORK_DIR/submenu-processed.wav \
                 fade t $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE
                rm -f $WORK_DIR/submenu.wav
                cp  $WORK_DIR/submenu-processed.wav $WORK_DIR/submenu.wav
            fi
            BGAUDIO_CMD3=(ffmpeg -i $WORK_DIR/submenu.wav \
            $AUDIO_OPTS -y $WORK_DIR/submenu.$AUDIO_EXT)
            if [ -s $WORK_DIR/submenu.$AUDIO_EXT ]; then # if exists do nothing
                :
            else
                echo "Running "${BGAUDIO_CMD3[@]}"" >> "$LOG_FILE.tmp" 2>&1
                ! "${BGAUDIO_CMD3[@]}" 2>&1 |strings >> "$LOG_FILE" \
                && runtime_error
            fi
        fi
        # copy the final file for each submenu if only 1 supplied
        "${COPY_AC3[@]}"
        yecho
        yecho "Multiplexing video and audio together"
        S=$((s + 1))
        MPLEX_CMD=(mplex -V -f $MPLEX_FORMAT -o $WORK_DIR/menu$S.mpg \
        $WORK_DIR/menu$s.$AUDIO_EXT $WORK_DIR/menu$s.m2v)
        echo "Running: "${MPLEX_CMD[@]}"" | fold -bs >> "$LOG_FILE"
        ! "${MPLEX_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"  && runtime_error
        # remove wav to save space
        rm -fv $WORK_DIR/menu$s.wav
    done
    rm -fv $WORK_DIR/submenu.{wav,$AUDIO_EXT}
    rm -fr $WORK_DIR/animenu/*
fi
##############################################################################
#                      Work on main menu                                     #
##############################################################################
if $DO_MENU; then
    yecho
    yecho "Building main menu"
fi
if [[ -n "$BG_VIDEO" ]] && ! $QUICK_MENU; then
    yecho "Getting background video from $BG_VIDEO"
    FFMPEG_CMD=(ffmpeg -ss $BG_SEEK -i "$BG_VIDEO" -vframes $BG_VIDEO_FRAMES \
    -s $VIDSIZE -sameq "$WORK_DIR/bg/%d.jpg")
    yecho "Extracting/resizing background images"
    echo "Running: ${FFMPEG_CMD[@]}" | format_output >> "$LOG_FILE"
    # Run command and check for failure
    if ! "${FFMPEG_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"; then
        runtime_error "Problem creating images from the background video"
    fi
    # make sure there are enough pics to make a bg video
    IMAGES=( "${IMAGES[@]}" \
    $(find $WORK_DIR/bg -maxdepth 1 -name \*[1-9]\*.jpg|sort) )
    last_pic=${#IMAGES[@]}
    num_bgpics=$last_pic
    next_pic=$(($last_pic + 1))
    if [ $last_pic -lt $MAX_MENU_LEN ]; then
        for ((l=next_pic; l<=MAX_MENU_LEN; l++)); do
            cp $WORK_DIR/bg/${last_pic}.jpg $WORK_DIR/bg/$l.jpg
        done
    fi
    unset IMAGES PICS last_pic next_pic
fi
if [[ -n "$SHOWCASE_VIDEO" ]] && $SC_THUMB; then
    echo "Getting showcase video images from $SHOWCASE_VIDEO"
    if [ "$SC_FRAMESTYLE" = "glass" ]; then
        # some vars for get_framed_pics()
        D=2
        FRAME_SIZE=$SHOWCASE_SIZE
        VOUT="png:z=7"
        MPLAYER_SEEK_VAL=$SHOWCASE_SEEK_VAL
        $SWITCHED_MODE && MPLAYER_SEEK_VAL=${SEEK_VAL[MENU_NUM-1]}
        get_framed_pics "$SHOWCASE_VIDEO"  >> "$LOG_FILE" 2>&1
        for ((i=0; i<=$FRAMES; i++)); do
            mv  "$WORK_DIR"/$(printf "%08d%s"  $((i+1)) .png) \
            "$WORK_DIR"/showcase/$(printf "%06d%s"  $((i+1)) .png) 2>/dev/null
        done
    elif [ "$SC_FRAMESTYLE" = "none" ]; then
        if $SWITCHED_MODE; then
            FFMPEG_SEEK_VAL=${SEEK_VAL[MENU_NUM-1]}
        else
            FFMPEG_SEEK_VAL=$SHOWCASE_SEEK_VAL
        fi

        FFMPEG_CMD=(ffmpeg -ss $FFMPEG_SEEK_VAL -i "$SHOWCASE_VIDEO" -s \
        $SHOWCASE_SIZE -vframes $FRAMES -an -y "$WORK_DIR/showcase/%06d.png")
        echo -e "\nRunning: "${FFMPEG_CMD[@]}"\n" | fold -bs >> "$LOG_FILE"
        SED_VAR="frame="
        "${FFMPEG_CMD[@]}" >> "$LOG_FILE.tmp" 2>&1 &
        ffm_pid=$!
        while ps -p $ffm_pid >/dev/null; do
            sleep 1
            spin $SPINNER
        done
        wait $ffm_pid
        (($?)) && runtime_error "Problem creating images from the video."
            
        strings "$LOG_FILE.tmp" >> "$LOG_FILE"
        rm -f "$LOG_FILE.tmp"
        echo
    fi
    for ((i=FIRST_PIC; i<LAST_PIC; i++)); do
        SC_PICS=( ${SC_PICS[@]} $(find $WORK_DIR/showcase -maxdepth 1 \
        -name $(printf "%06d%s"  $((i+1)) .png) ) )
    done
    $SWITCHED && $STATIC && SC_PICS=( "$WORK_DIR/showcase/000001.png" )
    if [[ "$SC_FRAMESTYLE" = "glass" ]] \
    &&  [[ -z "$ROTATE" && -z "$WAVE" ]]; then
        :
    else
        unset impids
        num_procs=0
        for p in ${!SC_PICS[@]}; do
            ((num_procs++)) # how many processes are running
            this_pic=$(sed 's,.*/,,;s/^0*//;s/.png//' <<< "${SC_PICS[p]}")
            pic="${SC_PICS[p]}"
            # if glass and either wave or rotate
            if [ "$SC_FRAMESTYLE" = "glass" ] && \
             [[ -n "$WAVE" || -n "$ROTATE" ]]; then
                { convert -size $SHOWCASE_SIZE "$pic" -background none \
                 $ROTATE $WAVE -resize $SHOWCASE_SIZE! "$pic" ; } &
            # if glass and neither wave or rotate
            elif [ "$SC_FRAMESTYLE" = "glass" ] && \
             [[ -z "$WAVE" && -z "$ROTATE" ]]; then
                :
            else # not glass
                if $SHOWCASE_3D && [[ -n $SHOWCASE_SHAPE ]]; then
                    CURVE_VARS="5 3 5 1 1"
                    unset SC_RAISE # 3D shaped thumbs have no -raise - use command below
                    . todisc-fade-routine
                    sc_3d_cmd=(convert - -write mpr:${p}img -fx A  +matte \
                    -blur 0x$( LC_ALL="C" bash -c "printf  "%.2f" \
                    $(bc_math "6.9 + .${CURVE_ARRAY[p]/.}")" ) -shade \
                    $(bc_math "115 + ${CURVE_ARRAY[p]}" int)x30 \
                    -normalize mpr:${p}img \
                    -compose Overlay -composite mpr:${p}img -matte \
                    -compose Dst_In -composite)
                else
                    sc_3d_cmd=(convert - $SC_RAISE)
                fi
                if [[ -n $SHOWCASE_SHAPE ]]; then
                    { composite -compose CopyOpacity $SHOWCASE_MASK +matte \
                    "$pic" miff:- |
                    "${sc_3d_cmd[@]}" miff:- |
                    convert $QUALITY -size $SHOWCASE_SIZE - -background none \
                    $ROTATE $WAVE -resize ${SHOWCASE_SIZE}! "$pic" ; } 2>> "$LOG_FILE" &
                else 
                    { convert -size $SHOWCASE_SIZE "$pic" $SC_RAISE miff:- |
                    convert - $SHOWCASE_FRAME -background none $ROTATE $WAVE miff:- |
                    convert - -$QUALITY  resize ${SHOWCASE_SIZE}! "$pic"  ; } \
                      2>> "$LOG_FILE" &
                fi
            fi
            impids="$impids $!"
            if ((num_procs==max_procs || p >= (${#SC_PICS[@]}-1) )); then
                spin "\rProcessing frame $this_pic of $LAST_PIC  "
                wait $impids
                unset impids num_procs
            fi
        done
    fi
    # make sure showcase video finishes at the time time as other menu items
    IMAGES=( $(find $WORK_DIR/showcase -maxdepth 1 -name 00\*.png|sort) )
    last_pic=$(( ${#IMAGES[@]} - 1 ))
    num_scpics=$last_pic
    next_pic=$(($last_pic + 1))
    if [ $last_pic -lt $MAX_MENU_LEN ] && ! $STATIC; then
        for ((l=next_pic; l<=MAX_MENU_LEN; l++)); do
            cp $WORK_DIR/showcase/$( printf %06d $last_pic).png \
            $WORK_DIR/showcase/$(printf %06d $l).png
        done
    fi

fi
# ani_pics is the largest # of animated image frames. Update this value
((num_bgpics > ani_pics)) && ani_pics=$num_bgpics
((num_scpics > ani_pics)) && ani_pics=$num_scpics
unset IMAGES last_pic next_pic FFMPEG_CMD pic

yecho
if [[ ! "$SC_FRAMESTYLE" = "glass" && ! $TEXTMENU ]]; then
    if $SHOWCASE; then
        yecho "Processing video images"
    else
        yecho "Adding title to video images and resizing"
    fi
fi
if ! $TEXTMENU && ! $SINGLE_SLIDESHOW && $DO_MENU; then
    for ((i=0; i<=NUM_FILES; i++)); do
        if $FEATHER && $THUMBS_3D && [ "$THUMB_SHAPE" != "normal" ]; then
            unset CURVE_ARRAY CURVE_VALUES CURVE_VARS
            CURVE_VARS="5 3 5 1 1"
            . todisc-fade-routine "3 5 5 1 1"
        fi
        PICS=( "${PICS[@]}" \
        $(find $WORK_DIR/pics/$i -maxdepth 1 -name \*[0-9]\*.$IMG_FMT|sort) )
        echo
        LAST_IMG=$LAST_PIC
        ((${#PICS[@]} < LAST_PIC)) && LAST_IMG=${#PICS[@]}
        if $STATIC; then
            START_PIC=0
            LAST_IMG=1
        else
            START_PIC=$FIRST_PIC
        fi
        yecho "Working on ${#PICS[@]} images from ${IN_FILES[i]}"
        num_procs=0
        for ((p=START_PIC; p<LAST_IMG; p++)); do
            ((num_procs++))
            # only let one process use the spinner at a time
            if ((num_procs==max_procs || p==LAST_IMG-1)); then
                spin "\rProcessing frame $((p+1)) "
            fi
            unset IM_CMD6
            [[ -n ${ROTATE_ARRAY[@]} ]] && \
            THUMB_ROTATE="-background none -rotate ${ROTATE_ARRAY[i]}"
            IM_CMD=(composite -compose CopyOpacity $THUMB_MASK \
            +matte "${PICS[p]}")
            #IM_CMD01=(convert "${PICS[p]}" -background '#101010' \
            #-bordercolor "#444744" $THUMB_FRAME )
            IM_CMD01=(convert "${PICS[p]}" -background '#101010' \
            -bordercolor $THUMB_FRAME_CLR $THUMB_FRAME )
            IM_CMD02=(convert "${PICS[p]}" $RAISE)
            IM_CMD03=(composite -compose CopyOpacity $THUMB_MASK +matte -)
            IM_CMD04=(convert - -background none \
            -bordercolor $THUMB_FRAME_CLR  "$WORK_DIR/thumb_title${i}.png" \
            -gravity south -geometry +0+5 -compose over -composite)
            IM_CMD1=(convert -resize ${THUMB_SIZE}! -)
            IM_CMD2=(composite -gravity center -compose DstOver \
            $WORK_DIR/feather_mask2.png -)
            ! $USE_FEATHER_MASK && IM_CMD2=(convert -)
            IM_CMD3=(convert "${PICS[p]}" -background none -bordercolor \
            $THUMB_FRAME_CLR $THUMB_FRAME "$WORK_DIR/thumb_title${i}.png" \
            -gravity south -geometry +0+5 -compose over -composite)
            IM_CMD4=(convert -background none -bordercolor $THUMB_FRAME_CLR \
            -border $THUMB_FRAME_SIZE -)
            IM_CMD4b=(convert -background none -bordercolor none \
            $THUMB_FRAME -)
            IM_CMD5=(convert -size ${THUMB_SIZE} - $QUALITY $THUMB_ROTATE \
            -resize ${THUMB_SIZE}! "${PICS[p]}")
            IM_CMD6=(convert - -write mpr:img${p} -fx A  +matte \
            -blur 0x$( LC_ALL="C" bash -c \
            "printf "%.2f" $(bc_math "7 + .${CURVE_ARRAY[p]/.}")" )  \
            -shade $(bc_math "115 + ${CURVE_ARRAY[p]}")x30 -normalize \
            mpr:img${p} -compose Overlay -composite mpr:img${p} \
            -matte -compose Dst_In -composite)
            IM_CMD7=(convert -trim +repage - )
            # single slideshow sets DO_FRAME to false - no titles
            ! $DO_FRAME && \
            IM_CMD04=(convert -) && IM_CMD3=(convert "${PICS[p]}")
            if $FEATHER &&  [ "$THUMB_SHAPE" != "normal" ] && $THUMBS_3D; then
                CURVE_UPDATE="with -blur 0x$( LC_ALL="C" bash -c \
                "printf  "%.2f" $(bc_math "7 + .${CURVE_ARRAY[p]/.}")" ) \
                -shade $( LC_ALL="C" bash -c "printf "%.2f" \
                $(bc_math "115 + ${CURVE_ARRAY[p]}")" )x30"
            fi
            if $FEATHER; then
                if $SHOWCASE; then
                    if $THUMBS_3D; then
                        if [ "$THUMB_SHAPE" != "normal" ]; then
                            { "${IM_CMD[@]}" miff:- | "${IM_CMD2[@]}" miff:- |
                            "${IM_CMD6[@]}" miff:- |  "${IM_CMD7[@]}" miff:- |
                            "${IM_CMD5[@]}" ; } 2>> "$LOG_FILE" &
                        else # normal thumbshape, with feather and 3D
                            { "${IM_CMD02[@]}" miff:- | "${IM_CMD03[@]}" miff:- |
                            "${IM_CMD2[@]}" miff:- |"${IM_CMD7[@]}" miff:- |
                            "${IM_CMD5[@]}" ; } 2>> "$LOG_FILE" &

                        fi
                    else
                        { "${IM_CMD[@]}" miff:- | "${IM_CMD2[@]}" miff:- |
                        "${IM_CMD5[@]}" ; } 2>> "$LOG_FILE" &
                    fi
                else # not SHOWCASE
                    if $THUMBS_3D; then
                        if [ "$THUMB_SHAPE" != "normal" ]; then
                            { "${IM_CMD[@]}" miff:- | "${IM_CMD6[@]}"  miff:- |
                            "${IM_CMD1[@]}" miff:- |"${IM_CMD04[@]}" miff:- |
                            "${IM_CMD1[@]}" miff:- | "${IM_CMD2[@]}" miff:- |
                            "${IM_CMD5[@]}" ; } 2>> "$LOG_FILE" &
                        else
                            { "${IM_CMD02[@]}" miff:- | "${IM_CMD04[@]}" miff:- |
                            "${IM_CMD2[@]}" miff:- |
                            "${IM_CMD5[@]}" ; } 2>> "$LOG_FILE" &
                        fi
                    else # not 3D
                        { "${IM_CMD[@]}" miff:- | "${IM_CMD04[@]}" miff:- |
                        "${IM_CMD1[@]}" miff:- |"${IM_CMD2[@]}" miff:- |
                        "${IM_CMD5[@]}" ; } 2>> "$LOG_FILE" &
                    fi
                fi
            else # not FEATHER
                if $SHOWCASE; then # showcase but not feather
                    if [[ "$SC_FRAMESTYLE" = "glass" \
                      && -z ${ROTATE_ARRAY[@]} ]]; then
                        :
                    else
                        if $THUMBS_3D; then
                            { "${IM_CMD02[@]}" miff:- | "${IM_CMD5[@]}" ; } \
                            2>> "$LOG_FILE" &
                        else
                            { "${IM_CMD01[@]}" miff:- | "${IM_CMD5[@]}" ; } \
                            2>> "$LOG_FILE" &
                        fi
                    fi
                else # not showcase or feather
                    if $THUMBS_3D; then
                        { "${IM_CMD02[@]}" miff:- | "${IM_CMD04[@]}" miff:- |
                        "${IM_CMD4[@]}" miff:- | "${IM_CMD5[@]}" ; } \
                        2>> "$LOG_FILE" &
                    else
                        { "${IM_CMD3[@]}" miff:- | "${IM_CMD5[@]}" ; } \
                        2>> "$LOG_FILE" &
                    fi
                fi
            fi
            title_pids="$title_pids $!"
            # wait on processes to keep on or below max # of processes
            if ((num_procs >= max_procs || i == LAST_IMG)); then
                wait
                unset num_procs title_pids
            fi
            if $STATIC; then unset PICS; fi
            unset IM_CMD0 IM_CMD1 IM_CMD2 IM_CMD3 IM_CMD4 IM_CMD5 IM_CMD6
        done
        wait
        # make sure all animated thumbs finish at the same time
        if ! $STATIC; then
            IMAGES=( "${IMAGES[@]}" \
            $(find $WORK_DIR/pics/$i -maxdepth 1 -name 00\*.$IMG_FMT|sort) )
            last_pic=$(( ${#IMAGES[@]} - 1 ))
            next_pic=$(($last_pic + 1))
            if (( (last_pic - 1) < MAX_MENU_LEN )) ; then
                for ((l=next_pic; l<=MAX_MENU_LEN; l++)); do
                    cp $WORK_DIR/pics/$i/$( printf %06d $last_pic).$IMG_FMT \
                    $WORK_DIR/pics/$i/$(printf %06d $l).$IMG_FMT
                done
            fi
            unset IMAGES last_pic next_pic
        fi
        unset PICS
    done
fi
if ! $QUICK_MENU && $DO_MENU; then
    yecho
    yecho "Making $FRAMES final montage frames and compositing onto \
    background with title"
    yecho
fi
if $STATIC; then
    # we have a value for MENU_AUDIOLEN AND BG_AUDIO
    if [[ -n "$BG_AUDIO" && "$BG_AUDIO" != "none" ]]; then
        LOOPS=$( bc <<< "$MENU_AUDIOLEN * $FRAME_RATE" 2>/dev/null)
        LOOPS=${LOOPS%.*}
    # switched menu: no bg audio or video and not menu fade
    elif $SWITCHED && [[ -z $BG_VIDEO && -z $BG_AUDIO ]] && ! $MENU_FADE; then
        LOOPS=60
    # any animation will use the full menu length
    elif [[ -n $BG_VIDEO || -n $SHOWCASE_VIDEO ]] || $MENU_FADE; then
        LOOPS=$FRAMES
    else
        # anything I've missed that is static will be 60 frames long :)
        LOOPS=60
    fi
    PPM_LOOPS=$LOOPS
fi
if ! $QUICK_MENU && $DO_MENU; then
    PIPE_FORMAT="-pix_fmt yuv420p -f yuv4mpegpipe"
    $STATIC && INSIZE="-s $VIDSIZE"
    echo
    echo \
    "Converting images to video and encoding to $TARGET-compliant format" >&2
    # convert images to video stream and encode to dvd compliant m2v
    [[ -n $PPM_LOOPS ]] && PPM_FRAMES=$PPM_LOOPS ||
    PPM_FRAMES=$((FRAMES))
    # extra black frames for menu fade at the end (check if doing fadeout 1st)
    fadevals=( $(. todisc-fade-routine && \
        echo ${ANIMENU_ENDFRAME} ${THUMBS_FADEOUT_STARTFRAME}) )
    (( ${fadevals[0]} > ${fadevals[1]} )) && $MENU_FADE && \
        PPM_FRAMES=$((PPM_FRAMES+18))
    TOYUV_CMD=(ppmtoy4m -v 2 -n $PPM_FRAMES -A 10:11 -I p -F $YUV_FR \
    -S 420mpeg2 -r)
    IMGENC_CMD=(ffmpeg $INSIZE -r $FRAME_RATE $PIPE_FORMAT -i - -an \
    -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
    -y $WORK_DIR/intro.m2v)
    yecho "Running ${TOYUV_CMD[@]} < $WORK_DIR/ppm.fifo | ${IMGENC_CMD[@]}" |
    fold -bs
    mkfifo "$WORK_DIR/ppm.fifo" 2>/dev/null
    mkfifo "$WORK_DIR/enc.fifo" 2>/dev/null
    "${TOYUV_CMD[@]}" < "$WORK_DIR/ppm.fifo" > "$WORK_DIR/enc.fifo" \
     2>> "$LOG_FILE" & #/dev/null &
    encpids="$encpids $!"
    "${IMGENC_CMD[@]}" <  "$WORK_DIR/enc.fifo"  2>> "$LOG_FILE" & #/dev/null &
    encpids="$encpids $!"
fi
# make intermediary fifos for images.  They will get catted to ppm.fifo
for ((n=1; n<=max_procs; n++)); do
    [[ ! -e "$WORK_DIR/temp-${n}.ppm" ]] && mkfifo "$WORK_DIR/temp-${n}.ppm"
done
# TODO use exec 2>> "$LOG_FILE" to save lines
if $MENU_FADE && ! $QUICK_MENU; then
    . todisc-fade-routine
    # ani_frames is the last animated frame
    ((THUMBS_FADEIN_ENDFRAME > ani_pics )) && \
     ani_frames=$THUMBS_FADEIN_ENDFRAME || ani_frames=$ani_pics
    yecho >&2
    yecho "Creating background fade first" >&2
    yecho >&2
    if [ -z "$BG_VIDEO" ]; then
        for ((frame=0; frame<=ANIMENU_ENDFRAME; frame++)); do
            # copy template for fade out beginning and end frames
            cp $WORK_DIR/pics/template.jpg $WORK_DIR/bg/$(($frame + 1)).jpg
        done
    fi
    unset bgfade_pids num_procs
    for ((frame=0; frame<=BG_FADEIN_ENDFRAME; frame++)); do
        ((num_procs++))
        D=`get_bg_opacity`
        composite -dissolve $D \
        $WORK_DIR/bg/$(($frame + 1)).jpg $WORK_DIR/black.ppm \
        $WORK_DIR/bg/$(($frame + 1)).jpg &
        bgfade_pids="$bgfade_pids $!"
        if ((num_procs >= max_procs || frame == BG_FADEIN_ENDFRAME)); then
            wait $bgfade_pids
            unset bgfade_pids num_procs
        fi
    done
    unset bgfade_pids num_procs
    for ((frame=BG_FADEOUT_STARTFRAME; frame<=BG_FADEOUT_ENDFRAME; frame++)); do
        #((num_procs++))
        D=`get_bg_opacity`
        composite -dissolve $D $WORK_DIR/bg/$frame.jpg \
        $WORK_DIR/black.ppm $WORK_DIR/bg/$frame.jpg
        #bgfade_pids="$bgfade_pids $!"
        #if ((num_procs >= max_procs || frame == BG_FADEOUT_ENDFRAME)); then
        #    wait $bgfade_pids
        #    unset bgfade_pids num_procs
        #fi
    done
    unset num_procs
    for ((frame=0; frame<ANIMENU_ENDFRAME; frame++)); do
        ((num_procs++)) # how many processes are running
        out_ppm="$WORK_DIR/temp-${num_procs}.ppm" # current frame
        # set dissolve vars from todisc-fade-routine functions
        BC=$(get_title_opacity)
        B=$(awk -F ':' '{print $1'}<<<$BC)
        C=$(awk -F ':' '{print $2'}<<<$BC)
        S=$(get_thumb_opacity)
        # experimental: allow using -menu-fade with static thumbs
        $STATIC && FRAME_NUM=0 || FRAME_NUM=$((frame + 1))

        for ((cnt=0; cnt<=NUM_FILES; cnt++)); do
            ANI_PICS=( "${ANI_PICS[@]}" $(find $WORK_DIR/pics/$cnt  \
            -name $(printf "%06d%s"  $FRAME_NUM .$IMG_FMT) ) )
        done
        if $SHOWCASE; then
            if ! $TEXTMENU; then
                for ((i=0; i<${#ANI_PICS[@]}; i++)); do
                    sc_cmd=( ${sc_cmd[@]} ${SHOWCASE_THUMB_PAGES[i]} \
                    "${ANI_PICS[i]}")
                done
            fi
            if $SC_THUMB; then
                SC_VIDEO_CMD="$SC_IMG_PAGE \
                "$WORK_DIR"/showcase/$(printf "%06d%s"  $(($frame + 1)) .png)"
            else
                unset SC_VIDEO_CMD
            fi
        fi
        $TEXTMENU && unset sc_cmd
        ! $TEXTMENU && MOSAIC="-mosaic"
        BG_PIC=$(find $WORK_DIR/bg -name $((frame + 1)).jpg)
        # create the montage from the images in each video dir
        MONTAGE_CMD=(convert  -size $VIDSIZE -background none \
        ${sc_cmd[@]} $SC_IMG_CMD $MOSAIC)
        MONTAGE_CMD01=(convert  -size $VIDSIZE xc:none -background none \
        ${sc_cmd[@]} $SC_VIDEO_CMD $MOSAIC)
        MONTAGE_CMD02=(convert -size $VIDSIZE -background none \
        - ${sc_thumb_title_cmd[@]} -mosaic)
        MONTAGE_CMD03=(convert -size $VIDSIZE -background none \
        ${sc_thumb_title_cmd[@]} -mosaic)
        MONTAGE_CMD1=(montage "${ANI_PICS[@]}" -tile ${TILE_ARRAY[NUM_FILES]} \
        -geometry ${THUMB_SIZE}${MTG_GEO} -background none)
        #  dissolve the finished montages onto the background
        MONTAGE_CMD2=(composite -dissolve $S -gravity $BUTTON_GRAVITY \
        -geometry +${XGEO}+${YGEO} - $WORK_DIR/bg/$((frame + 1)).jpg \
        -background none)
        MONTAGE_CMD2c=(composite -size $VIDSIZE -background none \
        -gravity NorthWest  -dissolve $S - $WORK_DIR/bg/$((frame + 1)).jpg \
        -background none)
        # if MIST is called for, this dissolves the mist onto the background
        MONTAGE_CMD3=(composite -dissolve $B -gravity $TITLE_GRAVITY \
        -geometry ${mist_xoffset}${mist_yoffset} $WORK_DIR/white.png -)
        # finally, dissolve title onto MIST (or background) and pipe out a ppm
        # write out a ppm if montages are static from here on in
        if (( frame == ani_frames)) || ((frame == BG_FADEIN_ENDFRAME )); then
            write_ppm=(-write "$WORK_DIR/montage-${frame}.ppm")
            copy_ppm="$WORK_DIR/montage-${frame}.ppm"
        else
            unset write_ppm
        fi
        MONTAGE_CMD4=(composite -dissolve $C -gravity $TITLE_GRAVITY \
        -geometry ${title_xoffset}${title_yoffset} $WORK_DIR/title_txt.png - \
        -background none -depth 8 ppm:- )
        if $PLAYALL ; then
            MONTAGE_CMD5=(composite -dissolve $S -gravity SouthEast -geometry \
            $PLAYALL_BTN_OFFSETS "$WORK_DIR/Playall.png" - \
            -background none miff:-)
        else
            MONTAGE_CMD5=(cat)
        fi
        if $TITLESET_MODE && ! $VMGM_ONLY && $VMGM_MENU; then
            MONTAGE_CMD6=(composite -dissolve $S -gravity $RTN_BTN_GRAVITY \
            -geometry $RTN_BTN_OFFSETS "$WORK_DIR/Main.png" - \
            -background none miff:-)
        else
            MONTAGE_CMD6=(cat)
        fi
        MONTAGE_CMD7=(convert - -depth 8  "${write_ppm[@]}" "$out_ppm")
        # -menu-fade working with -static
        $SINGLE_SLIDESHOW && \
        IM_CMD1=(convert "$WORK_DIR/polaroid_stack.png" miff:- )

        $TEXTMENU && unset MONTAGE_CMD
        $TEXTMENU && MONTAGE_CMD=( "${MONTAGE_CMD03[@]}" )
        # if doing less animated frames than the total # of frames
        # break from the loop and use ppmtoy4m to repeat last frame
        # if we are not doing a fadeout, or if doing fadeout, cat the last
        # animated frame in the loop till we reach the start of the fadeout
        # if we have a static background, then cat frames from the frame the bg
        # finishes fading in, to the frame where the title starts to fade in

        # make sure we don't start copying frames if fadein is not finished
        #f=$((frame + 2))
        f=$((frame + 1))
        if ((frame==ani_frames+1)); then
            cat_fifos=false
            endframe=$THUMBS_FADEOUT_STARTFRAME
            copy_frames=$((endframe - f))
            # no fadeout, just let ppmtoy4m repeat last frame till done
            if ((ANIMENU_ENDFRAME<=THUMBS_FADEOUT_STARTFRAME)); then
                spin  "\rEncoding frames $f to $endframe  " >&2
                if [[ -n ${ppm_fifos[@]} ]]; then
                    cat "${ppm_fifos[@]}"
                fi
                echo >&2
                break
            else
                # cat any backlog of backgrounded processes
                if [[ -n ${ppm_fifos[@]} ]]; then
                    cat "${ppm_fifos[@]}"
                fi
                if [[ -s "$copy_ppm" ]]; then
                    # endframe is the last unchanging frame in the video
                    for ((i=0; i<copy_frames; i++)); do
                        spin  "\rEncoding frames $f to $endframe  " >&2
                        cat "$copy_ppm"
                    done
                    total_frames=$((total_frames+copy_frames))
                    unset ppm_fifos num_procs
                    frame=$endframe
                fi
            fi
        elif [[ -z $BG_VIDEO ]] && ((frame==BG_FADEIN_ENDFRAME+1)); then
            # cat any backlog of backgrounded processes
            if [[ -n ${ppm_fifos[@]} ]]; then
                cat "${ppm_fifos[@]}"
            fi
            cat_fifos=false
            t_frames=$(( (TITLE_FADEIN_STARTFRAME) - (BG_FADEIN_ENDFRAME+1)))
            total_frames=$((total_frames+t_frames))
            for ((i=BG_FADEIN_ENDFRAME+1;
             i<TITLE_FADEIN_STARTFRAME; i++)); do
                spin "Encoding frames $f to $((TITLE_FADEIN_STARTFRAME-1)) " >&2
                cat "$copy_ppm"
            done
            rm -f "$WORK_DIR/montage.ppm" >&2
            unset ppm_fifos num_procs
            frame=$((TITLE_FADEIN_STARTFRAME-1))
        else
            ppm_fifos+=("$out_ppm") # all frames waiting to be processed
            cat_fifos=:
        fi

        # pipe all of above commands if using MIST
        if $MIST && $cat_fifos; then
            if $SHOWCASE; then
                if [[ -n "$SHOWCASE_VIDEO" ]]; then
                    { "${MONTAGE_CMD01[@]}" miff:-|"${MONTAGE_CMD02[@]}" miff:- |
                    "${MONTAGE_CMD2c[@]}" miff:- |"${MONTAGE_CMD3[@]}" miff:- |
                    "${MONTAGE_CMD5[@]}" | "${MONTAGE_CMD6[@]}" |
                    "${MONTAGE_CMD4[@]}" | "${MONTAGE_CMD7[@]}" ; } \
                    2>> "$LOG_FILE" &
                else # not SHOWCASE_VIDEO (SHOWCASE_IMG)
                    { "${MONTAGE_CMD[@]}" miff:- | "${MONTAGE_CMD02[@]}" miff:- |
                    "${MONTAGE_CMD2c[@]}" miff:- |"${MONTAGE_CMD5[@]}" |
                    "${MONTAGE_CMD6[@]}" | "${MONTAGE_CMD3[@]}" miff:- |
                    "${MONTAGE_CMD4[@]}" | "${MONTAGE_CMD7[@]}" ; } \
                    2>> "$LOG_FILE" &
                fi
            else # not SHOWCASE
                { "${MONTAGE_CMD1[@]}" miff:- | "${MONTAGE_CMD2[@]}" miff:- |
                "${MONTAGE_CMD3[@]}" miff:- | "${MONTAGE_CMD5[@]}" |
                "${MONTAGE_CMD6[@]}" | "${MONTAGE_CMD4[@]}" |
                "${MONTAGE_CMD7[@]}" ; } 2>> "$LOG_FILE" &
            fi
        elif ! $MIST && $cat_fifos; then  # no mist
            if $SHOWCASE; then
                if [[ -n "$SHOWCASE_VIDEO" ]]; then
                    { "${MONTAGE_CMD01[@]}" miff:-|"${MONTAGE_CMD02[@]}" miff:- |
                    "${MONTAGE_CMD2c[@]}" miff:- |"${MONTAGE_CMD5[@]}" |
                    "${MONTAGE_CMD6[@]}" | "${MONTAGE_CMD4[@]}" |
                    "${MONTAGE_CMD7[@]}" ; } 2>> "$LOG_FILE" &
                else
                    { "${MONTAGE_CMD[@]}" miff:- | "${MONTAGE_CMD02[@]}" miff:- |
                    "${MONTAGE_CMD2c[@]}" miff:- |"${MONTAGE_CMD5[@]}" |
                    "${MONTAGE_CMD6[@]}" | "${MONTAGE_CMD4[@]}" |
                    "${MONTAGE_CMD7[@]}" ; } 2>> "$LOG_FILE" &
                fi
            else
                { "${MONTAGE_CMD1[@]}" miff:- | "${MONTAGE_CMD2[@]}" miff:- |
                "${MONTAGE_CMD5[@]}" | "${MONTAGE_CMD6[@]}" |
                "${MONTAGE_CMD4[@]}"  | "${MONTAGE_CMD7[@]}" ; } \
                2>> "$LOG_FILE" &
            fi
        fi
        impids="$impids $!"
        rmpics+=( "$WORK_DIR/bg/$((frame+1)).jpg" )
        rmpics+=( "$WORK_DIR"/showcase/$(printf "%06d%s"  $(($frame + 1)) .png) )
        # we reuse thumbs for static so don't rm ANI_PICS
        ! $STATIC && rmpics+=( "${ANI_PICS[@]}" )

        ((total_frames++))
        unset ANI_PICS sc_cmd writeppm
        if ((num_procs==max_procs || frame >= ANIMENU_ENDFRAME-1)) && $cat_fifos; then
            spin  "\rProcessing frame $(($frame + 1))  " >&2
            cat "${ppm_fifos[@]}"
            wait $impids
            rm -f "${rmpics[@]}"
            unset num_procs ppm_fifos impids rmpics
        fi
    done > "$WORK_DIR/ppm.fifo"
elif ! $MENU_FADE && ! $QUICK_MENU && $DO_MENU; then # Do not do menu fade
    if $TRANSPARENT; then # non transparent -showcase-* uses this block too
        num_procs=0
        for (( count=1; count<=$FRAMES; count++)); do
            ((num_procs++)) # how many processes are running
            out_ppm="$WORK_DIR/temp-${num_procs}.ppm" # current frame
            ppm_fifos+=("$out_ppm") # all frames waiting to be processed
            if ((num_procs==max_procs || count==FRAMES)); then
                spin "\rProcessing frame $count  " >&2
            fi
            # experimental: allow using -menu-fade with static thumbs
            $STATIC && FRAME_NUM=0 || FRAME_NUM=$((count - 1))

            for ((cnt=0; cnt<=NUM_FILES; cnt++)); do
                ANI_PICS=( "${ANI_PICS[@]}" $(find $WORK_DIR/pics/$cnt  \
                -name $(printf "%06d%s"  $FRAME_NUM .$IMG_FMT) ) )
            done
            for ((f=0; f<${#ANI_PICS[@]}; f++)); do
                sc_cmd=( ${sc_cmd[@]} \
                ${SHOWCASE_THUMB_PAGES[f]} "${ANI_PICS[f]}")
            done
            SC_VIDEO_CMD="$SC_IMG_PAGE \
            "$WORK_DIR"/showcase/$(printf "%06d%s"  $count .png)"
            $STATIC && [[ -z $SHOWCASE_VIDEO ]] && SC_VIDEO_CMD="$SC_IMG_PAGE \
            "$WORK_DIR"/showcase_img.png"
            $TEXTMENU && unset sc_cmd

            IM_CMD0=(convert  -size $VIDSIZE "$WORK_DIR/pics/template.png" \
            ${sc_cmd[@]} $SC_IMG_CMD -mosaic)
            IM_CMD01=(convert  -size $VIDSIZE xc:none -background none \
            ${sc_cmd[@]} $SC_VIDEO_CMD ${sc_thumb_title_cmd[@]} -mosaic)
            # dissolve piped images onto bgimage
            IM_CMD02=(composite -gravity NorthWest -dissolve $OPACITY - \
            $WORK_DIR/pics/template.png)
            # dissolve piped images onto bgvideo
            IM_CMD03=(composite -size $VIDSIZE -background none \
            -gravity NorthWest  -dissolve $OPACITY - $WORK_DIR/bg/$count.jpg \
            -background none)
            # dissolve titles onto bgvideo
            IM_CMD04=(convert -size $VIDSIZE -background none \
             - ${sc_thumb_title_cmd[@]} -mosaic)
            IM_CMD05=(convert  -size $VIDSIZE xc:none -background none \
            ${sc_cmd[@]} $SC_IMG_CMD ${sc_thumb_title_cmd[@]} -mosaic)
            IM_CMD1=(montage ${ANI_PICS[@]} -tile ${TILE_ARRAY[NUM_FILES]} \
            -geometry ${THUMB_SIZE}${MTG_GEO} -background none miff:-)
            IM_CMD2=(composite -dissolve $OPACITY \
            -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} - \
            $WORK_DIR/pics/template.jpg -background none miff:-)
            IM_CMD2b=(composite -dissolve $OPACITY \
            -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} - \
            $WORK_DIR/bg/$count.jpg -background none miff:-)
            IM_CMD3=(composite -dissolve 30 -gravity $TITLE_GRAVITY \
            -geometry ${mist_xoffset}${mist_yoffset} \
            $WORK_DIR/white.png - miff:-)
            IM_CMD4=(convert -depth 8 - $WORK_DIR/title_txt.png -gravity \
            $TITLE_GRAVITY -geometry ${title_xoffset}${title_yoffset} \
            -composite "${ADD_RTN_BTN[@]}" "${ADD_PLAYALL_BTN[@]}" \
            "$out_ppm" )
            $SINGLE_SLIDESHOW && \
            IM_CMD1=(convert "$WORK_DIR/polaroid_stack.png" miff:- )
            if $MIST; then
                # showcase, mist, showcase-video
                if $SHOWCASE && [[ -n "$SHOWCASE_VIDEO" ]]; then
                    if test -n "$BG_VIDEO"; then # also bgvideo
                        { "${IM_CMD01[@]}" miff:- |
                       "${IM_CMD03[@]}" miff:- |  "${IM_CMD3[@]}" |
                        "${IM_CMD4[@]}" ; } &
                    else # not with bgvideo
                        { "${IM_CMD01[@]}" miff:- |
                        "${IM_CMD02[@]}" -depth 8 "$out_ppm" ; } &
                    fi
                # showcase, mist, showcase-image
                elif $SHOWCASE && [[ -n "$SHOWCASE_IMG" ]]; then
                    # showcase, mist, showcase-image with bgvideo
                    if test -n "$BG_VIDEO"; then
                        { "${IM_CMD05[@]}" miff:- |
                        "${IM_CMD03[@]}" miff:- |"${IM_CMD3[@]}" |
                        "${IM_CMD4[@]}" ; } &
                    else # showcase, mist, showcase-image, not bgvideo
                        { "${IM_CMD0[@]}" -depth 8 "$out_ppm" ; } &
                    fi
                elif ! $SHOWCASE; then
                    if test -n "$BG_VIDEO"; then
                        { "${IM_CMD1[@]}" | "${IM_CMD2b[@]}" | "${IM_CMD3[@]}" |
                        "${IM_CMD4[@]}" ; } 2>> "$LOG_FILE" &
                    else
                    { "${IM_CMD1[@]}" | "${IM_CMD2[@]}" | "${IM_CMD3[@]}" |
                    "${IM_CMD4[@]}" ; } 2>> "$LOG_FILE" &
                    fi
                fi
            else # showcase, no mist, showcase-video
                if $SHOWCASE && [[ -n "$SHOWCASE_VIDEO" ]]; then
                    if test -n "$BG_VIDEO"; then
                        # with bgvideo
                        { "${IM_CMD01[@]}" miff:- |
                        "${IM_CMD03[@]}" miff:- | "${IM_CMD4[@]}" ; } \
                        2>> "$LOG_FILE" &
                    else # no bgvideo
                        { "${IM_CMD01[@]}" $pngpipe |
                        "${IM_CMD02[@]}"  $pngpipe | "${IM_CMD4[@]}" ; } \
                        2>> "$LOG_FILE" &
                    fi
                elif $SHOWCASE && [[ -n "$SHOWCASE_IMG" ]]; then
                # showcase, no mist, showcase-image
                    if test -n "$BG_VIDEO"; then # with bgvideo
                        { "${IM_CMD05[@]}" miff:- |
                        "${IM_CMD03[@]}" miff:- | "${IM_CMD4[@]}" ; } \
                        2>> "$LOG_FILE" &
                    else # no bgvideo
                        { "${IM_CMD0[@]}" -depth 8 "$out_ppm" ; } \
                        2>> "$LOG_FILE" &
                    fi
                elif ! $SHOWCASE; then
                    if test -n "$BG_VIDEO"; then
                        { "${IM_CMD1[@]}" |
                         "${IM_CMD2b[@]}" | "${IM_CMD4[@]}" ; } \
                        2>> "$LOG_FILE" &
                    else
                        { "${IM_CMD1[@]}" | "${IM_CMD2[@]}" |
                        "${IM_CMD4[@]}" ; } 2>> "$LOG_FILE" &
                    fi
                fi
            fi
            impids="$impids $!"
            # remove images after they are used each cat run
            rmpics+=( "$WORK_DIR"/showcase/$(printf "%06d%s"  $count .png) )
            rmpics+=( "$WORK_DIR/bg/$count.jpg" )
            # we reuse thumbs for static so don't rm ANI_PICS
            ! $STATIC && rmpics+=( "${ANI_PICS[@]}" )
            if ((num_procs==max_procs || count >= FRAMES)); then
                cat "${ppm_fifos[@]}"
                wait $impids
                rm -f "${rmpics[@]}"
                unset num_procs ppm_fifos impids rmpics
                # remove now unneeded images to keep disc usage low
            fi
            unset ANI_PICS sc_cmd
        done > "$WORK_DIR/ppm.fifo"
    else # Not transparent (non transparent showcase uses transparent block ^^)
        C=$((${CHAPTERS[s]} - 1))
        num_procs=0
        for (( count=1; count <=FRAMES; count++)); do
            ((num_procs++)) # how many processes are running
            out_ppm="$WORK_DIR/temp-${num_procs}.ppm" # current frame
            ppm_fifos+=("$out_ppm") # all frames waiting to be processed
            if ((num_procs==max_procs || count==FRAMES)); then
                spin -ne "\rProcessing frame $count  " >&2
            fi
            $STATIC && FRAME_NUM=0 || FRAME_NUM=$((count - 1))

            for ((cnt=0; cnt<=NUM_FILES; cnt++)); do
                ANI_PICS=( "${ANI_PICS[@]}" \
                $(find $WORK_DIR/pics/$cnt \
                -name $(printf "%06d%s" $FRAME_NUM  .$IMG_FMT) ) )
            done
            # make final montages and composite onto grey background with title
            IM_CMD0=(montage ${ANI_PICS[@]} -tile ${TILE_ARRAY[NUM_FILES]} \
            -geometry ${THUMB_SIZE}${MTG_GEO} -background none miff:-)
            IM_CMD1=(convert $WORK_DIR/pics/template.jpg \
            -  -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} \
            -composite miff:-)
            IM_CMD2=(convert $WORK_DIR/bg/$count.jpg \
            -  -gravity $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} \
            -composite miff:-)
            IM_CMD3=(composite -dissolve 30 -gravity $TITLE_GRAVITY -geometry \
            ${mist_xoffset}${mist_yoffset} $WORK_DIR/white.png - miff:-)
            IM_CMD4=(convert -depth 8 - $WORK_DIR/title_txt.png -gravity \
            $TITLE_GRAVITY -geometry ${title_xoffset}${title_yoffset} \
            -composite "${ADD_RTN_BTN[@]}" "${ADD_PLAYALL_BTN[@]}" "$out_ppm" )
            $SINGLE_SLIDESHOW && \
            IM_CMD0=(convert "$WORK_DIR/polaroid_stack.png" miff:- )

            if test -n "$BG_VIDEO"; then
                if $MIST; then
                    { "${IM_CMD0[@]}" | "${IM_CMD2[@]}" | "${IM_CMD3[@]}" |
                    "${IM_CMD4[@]}" ; } 2>> "$LOG_FILE" &
                else # no mist
                    { "${IM_CMD0[@]}" | "${IM_CMD2[@]}" | "${IM_CMD4[@]}" ; } \
                    2>> "$LOG_FILE" &
                fi
            else # no bg video
                if $MIST; then
                    { "${IM_CMD0[@]}" | "${IM_CMD1[@]}" | "${IM_CMD3[@]}" |
                    "${IM_CMD4[@]}" ; } 2>> "$LOG_FILE" &
                else # no mist
                    { "${IM_CMD0[@]}" | "${IM_CMD1[@]}" | "${IM_CMD4[@]}" ; } \
                    2>> "$LOG_FILE" &
                fi
            fi
            impids="$impids $!"
            rmpics+=( "$WORK_DIR/bg/$count.jpg" )
            # static reuses the thumbs so don't rm each cat run
            ! $STATIC && rmpics+=( "${ANI_PICS[@]}" )
            if ((num_procs==max_procs || count >= FRAMES)); then
                cat "${ppm_fifos[@]}"
                wait $impids
                rm -f "${rmpics[@]}"
                unset num_procs ppm_fifos impids rmpics
            fi
            unset ANI_PICS
        done > "$WORK_DIR/ppm.fifo"
    fi
fi # end making final montages
# wait for ppmtoy4m and ffmpeg to finish
wait

if ! $QUICK_MENU && $DO_MENU; then
    echo
    echo "Cleaning up montage images"
    rm -f $WORK_DIR/animenu/*.jpg
    rm -f $WORK_DIR/animenu/*.png
fi
# check if m2v was created ok before proceeding
if $DO_MENU; then
    if ! mencoder -quiet -oac pcm -ovc copy -frames 0 \
      "$WORK_DIR/intro.m2v" -o /dev/null &> /dev/null; then
        echo
        runtime_error  "The menu video file has not been created !"
    fi
fi
if $DO_MENU; then
    MENU_ATIME=$(vid_length "$WORK_DIR/intro.m2v")
    $SWITCHED && MENU_ATIME=${MENU_LEN[MENU_NUM-1]}
fi

# use mplayer to dump audio if mplayer used for video
# but first check if audio same file as video and its not a static menu
if [[ $SC_FRAMESTYLE = "glass" && $BG_AUDIO = $SHOWCASE_VIDEO ]]; then
    ! $STATIC && USE_MPLAYER_4AUDIO=:
fi
BG_AUDIO_LENGTH="-t $MENU_ATIME"
# create audio background for the main menu
if $DO_MENU; then
    sample_size=$(get_sox_arg)
    if [[ -z "$BG_AUDIO" || "$BG_AUDIO" = "none" ]]; then # use silence
        ! $SWITCHED && AUDIO_FADE=false # do not fade silence
        echo "Running cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 \
        $sample_size -s - $WORK_DIR/intro.wav  trim 0 $MENU_ATIME" |fold -bs
        cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 \
        $sample_size -s - $WORK_DIR/intro.wav  trim 0 $MENU_ATIME
    # Make sure file exists
    elif test ! -s "$BG_AUDIO"; then
        runtime_error "Cannot find background audio file: $BG_AUDIO"
    else # audio supplied: convert to wav then later to dvd/svcd format
        # TODO if ! $BG_AUDIOVIDEO_FILE; then  # check if same file and if so
        # decode the audio and jpegs in one step above, and skip this block
        if $USE_MPLAYER_4AUDIO; then
            BGAUDIO_CMD=(mplayer  -quiet -vc null -vo null -ss \
            $MPLAYER_SEEK_VAL -ao pcm:waveheader:file="$WORK_DIR/intro.wav" \
            -endpos $MENU_ATIME  "$BG_AUDIO")
        else
            BGAUDIO_CMD=(ffmpeg -y -async 1 -ss $BG_AUDIO_SEEK \
            $BG_AUDIO_LENGTH -i "$BG_AUDIO" -r $FRAME_RATE -ar 48000 \
            -acodec pcm_s16le $WORK_DIR/intro.wav)
        fi
        yecho
        echo "Running ${BGAUDIO_CMD[@]}" |format_output|tee -a "$LOG_FILE" 2>&1
        ! "${BGAUDIO_CMD[@]}" 2>&1 |strings >> "$LOG_FILE" && runtime_error

        if $AUDIO_FADE; then  # bgaudio supplied and audio fade selected
            WAV_TIME=$(audio_length "$WORK_DIR/intro.wav")
            echo "Running:
            sox $WORK_DIR/intro.wav $WORK_DIR/intro-processed.wav fade t
            $FADE $WAV_TIME $FADE" |format_output
            sox $WORK_DIR/intro.wav \
            $WORK_DIR/intro-processed.wav fade t $FADE $WAV_TIME $FADE
            rm $WORK_DIR/intro.wav
            mv $WORK_DIR/intro-processed.wav $WORK_DIR/intro.wav
        fi
    fi
fi
unset BGAUDIO_CMD TIME

# convert to proper audio format
# temporarily have to use mp2enc for svcd as ffmpeg broken FIXME
# see r2162 todisc or older for how to fix this block when ffmpeg is fixed
BGAUDIO_CMD=(ffmpeg -i $WORK_DIR/intro.wav \
$AUDIO_OPTS -y $WORK_DIR/intro.$AUDIO_EXT)
yecho "Running "${BGAUDIO_CMD[@]}"" | fold -bs >> "$LOG_FILE"
"${BGAUDIO_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"
if $DO_MENU; then
     ! [[ -s $WORK_DIR/intro.$AUDIO_EXT ]] && runtime_error
    unset BGAUDIO_CMD
    rm -fv "$WORK_DIR/intro.wav"
    echo
    echo "Multiplexing main menu audio and video together"
    # mplex main menu audio and video together
    INTRO_MPLEX_CMD="mplex -V -f $MPLEX_FORMAT -o $WORK_DIR/intro.mpg \
      $WORK_DIR/intro.$AUDIO_EXT $WORK_DIR/intro.m2v"
    echo -e "\nRunning: $INTRO_MPLEX_CMD\n" |fold -bs >> "$LOG_FILE"
    yecho
    ! ${INTRO_MPLEX_CMD[@]} 2>&1 |strings >> "$LOG_FILE" && runtime_error

    yecho
    if $SWITCHED_MODE || $SWITCHED_MENUS; then
        yecho "Copying the menu mpeg"
        if [[ $MENU_NUM -ne 1 ]]; then
            cp -v "$REAL_WORK_DIR/intro.mpg" \
              "$BASEDIR/${TSET_NUM}-${MENU_NUM}intro.mpg"
        else
            cp -v  "$REAL_WORK_DIR/intro.mpg"  \
              "$REAL_WORK_DIR/${TSET_NUM}-${MENU_NUM}intro.mpg"
        fi
        sleep 2
        if $SWITCHED_MODE; then
            $KEEP_FILES && mv -v "$REAL_WORK_DIR" \
              "$BASEDIR"/TITLESET${TSET_NUM}-MENU${MENU_NUM}
            ( KEEP_FILES=false && cleanup )
            exit
        fi
    fi
    if $SWITCHED_MENUS; then
        for ((i=1; i<=${#FILES[@]}; i++)); do
            MENU_FILE="$BASEDIR/animenu${TSET_NUM}-${i}.mpg"
            yecho "Running spumux "$SPUMUX_XML" \
              < "$REAL_WORK_DIR/${TSET_NUM}-${i}intro.mpg" > "$MENU_FILE""
            spumux "$SPUMUX_XML" < "$WORK_DIR/${TSET_NUM}-${i}intro.mpg" \
              > "$MENU_FILE" 2>> "$LOG_FILE"
            check_menufile
        done
    fi
fi
if ! $SWITCHED_MENUS && ! $SWITCHED_MODE; then
    yecho "Running spumux "$SPUMUX_XML" < $WORK_DIR/intro.mpg > "$MENU_FILE""
    spumux "$SPUMUX_XML" < $WORK_DIR/intro.mpg > "$MENU_FILE" 2>> "$LOG_FILE"
    check_menufile
fi
if $SUB_MENU; then
    echo "Creating submenus"
    for ((x=1; x<=V_TOTAL; x++)); do
        yecho "Running spumux "$WORK_DIR/submenu${x}_spumux.xml" < \
        $WORK_DIR/menu${x}.mpg > \
        $(sed 's/\(.*\)menu/\1Menu/' <<< $WORK_DIR/menu${x}.mpg)"|fold -bs
        spumux "$WORK_DIR/submenu${x}_spumux.xml" < \
        $WORK_DIR/menu${x}.mpg > \
        $(sed 's/\(.*\)menu/\1Menu/' <<< $BASEDIR/${TSET_NUM}-menu${x}.mpg) \
        2>> "$LOG_FILE"
    done
fi
if $TITLESET_MODE; then
    $KEEP_FILES && mv -v "$REAL_WORK_DIR" "$BASEDIR"/TITLESET${TSET_NUM}
fi

if $AUTHOR && ! $VMGM_ONLY && ! $DO_TITLESETS && ! $SWITCHED_MODE; then
    echo "Running dvdauthor to create the DVD filesystem"
    dvdauthor -x "$DVDAUTHOR_XML" 2>&1  | tee -a  "$LOG_FILE.tmp"
    if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
        dvdauthor_error
    fi
    strings "$LOG_FILE.tmp" >> "$LOG_FILE" && rm -f "$LOG_FILE.tmp"
fi
echo "Cleaning up unwanted files in $REAL_WORK_DIR"
#find "$WORK_DIR"/ -name '*.png' ! -name Highlight.png ! -name Select.png \
#-exec rm -f {} \; > /dev/null 2>&1
find "$WORK_DIR"/ -name '*.jpg' ! -name preview.jpg -exec rm -f {} \; \
> /dev/null 2>&1
rm -fr "$WORK_DIR/animenu" "$WORK_DIR/pics" "$WORK_DIR/submenu"
$VMGM_ONLY && $KEEP_FILES && mv -v "$REAL_WORK_DIR" "$BASEDIR"/VMGM
if ! $VMGM_ONLY && ! $SWITCHED_MODE && ! $TITLESET_MODE && ! $DO_TITLESETS; then
    thanks_goodbye
    $BURN && burn_disc
fi
! $DO_TITLESETS && cleanup

